commit d6cde0c05ead9f15b87ebd8156748c980b296374 Author: Scott Bissmeyer Date: Mon Apr 7 07:44:27 2025 -0700 first commit diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6b76b4f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/EXE/GetCoreTempInfo.dll b/EXE/GetCoreTempInfo.dll new file mode 100644 index 0000000..8197d27 Binary files /dev/null and b/EXE/GetCoreTempInfo.dll differ diff --git a/EXE/VCTemp.exe b/EXE/VCTemp.exe new file mode 100644 index 0000000..fb3a904 Binary files /dev/null and b/EXE/VCTemp.exe differ diff --git a/GetCoreTempInfo.dll b/GetCoreTempInfo.dll new file mode 100644 index 0000000..8197d27 Binary files /dev/null and b/GetCoreTempInfo.dll differ diff --git a/LibreHardwareMonitor-0.9.4/.editorconfig b/LibreHardwareMonitor-0.9.4/.editorconfig new file mode 100644 index 0000000..c53ad35 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/.editorconfig @@ -0,0 +1,178 @@ +# editorconfig.org + +# top-most EditorConfig file +root = true + +# Default settings: +# A newline ending every file +# Use 4 spaces as indentation +[*] +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +end_of_line = lf + +[project.json] +indent_size = 2 + +# C# files +[*.{cs,vb}] + +# New line preferences +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_switch_labels = true +csharp_indent_labels = one_less_than_current + +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion + +# avoid this. unless absolutely necessary +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# Types: use keywords instead of BCL types, and permit var only when the type is clear +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = false:none +csharp_style_var_elsewhere = false:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# name all constant fields using PascalCase +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.required_modifiers = const +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +# static fields should have s_ prefix +dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion +dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields +dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style +dotnet_naming_symbols.static_fields.applicable_kinds = field +dotnet_naming_symbols.static_fields.required_modifiers = static +dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected +dotnet_naming_style.static_prefix_style.required_prefix = _ +dotnet_naming_style.static_prefix_style.capitalization = camel_case + +# internal and private fields should be _camelCase +dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion +dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style +dotnet_naming_symbols.private_internal_fields.applicable_kinds = field +dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal +dotnet_naming_style.camel_case_underscore_style.required_prefix = _ +dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case + +# Code style defaults +csharp_using_directive_placement = outside_namespace:suggestion +dotnet_sort_system_directives_first = true +csharp_prefer_braces = true:silent +csharp_preserve_single_line_blocks = true:none +csharp_preserve_single_line_statements = false:none +csharp_prefer_static_local_function = true:suggestion +csharp_prefer_simple_using_statement = false:none +csharp_style_prefer_switch_expression = true:suggestion +dotnet_style_readonly_field = true:suggestion + +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +csharp_prefer_simple_default_expression = true:suggestion + +# Expression-bodied members +csharp_style_expression_bodied_methods = true:silent +csharp_style_expression_bodied_constructors = true:silent +csharp_style_expression_bodied_operators = true:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = true:silent + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion + +# Null checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Other features +csharp_style_prefer_index_operator = false:none +csharp_style_prefer_range_operator = false:none +csharp_style_pattern_local_over_anonymous_function = false:none + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = do_not_ignore +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Analyzers +dotnet_code_quality.ca1802.api_surface = private, internal + +# CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1591.severity = suggestion + +# Xml project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] +indent_size = 2 + +[*.{csproj,vbproj,proj,nativeproj,locproj}] +charset = utf-8 + +# Xml files +[*.{xml,stylecop,resx,ruleset}] +indent_size = 2 + +# Xml config files +[*.{props,targets,config,nuspec}] +indent_size = 2 + +# YAML config files +[*.{yml,yaml}] +indent_size = 2 diff --git a/LibreHardwareMonitor-0.9.4/.github/FUNDING.yml b/LibreHardwareMonitor-0.9.4/.github/FUNDING.yml new file mode 100644 index 0000000..3ab8d83 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [phyxionnl] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/LibreHardwareMonitor-0.9.4/.github/dependabot.yml b/LibreHardwareMonitor-0.9.4/.github/dependabot.yml new file mode 100644 index 0000000..687cadc --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/.github/dependabot.yml @@ -0,0 +1,20 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + # LibreHardwareMonitor.csproj + - package-ecosystem: "nuget" + directory: "/LibreHardwareMonitor" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + + # LibreHardwareMonitorLib.csproj + - package-ecosystem: "nuget" + directory: "/LibreHardwareMonitorLib" + schedule: + interval: "daily" + open-pull-requests-limit: 10 diff --git a/LibreHardwareMonitor-0.9.4/.github/workflows/master.yml b/LibreHardwareMonitor-0.9.4/.github/workflows/master.yml new file mode 100644 index 0000000..4faf638 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/.github/workflows/master.yml @@ -0,0 +1,75 @@ +name: master + +on: + push: + branches: [master] + +jobs: + build: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + - uses: nuget/setup-nuget@v2 + - uses: microsoft/setup-msbuild@v1.1 + with: + msbuild-architecture: x64 + + - uses: dorny/paths-filter@v2 + id: changes + with: + filters: | + buildprops: + - 'Directory.Build.props' + + - name: Update version + if: steps.changes.outputs.buildprops == 'false' + run: | + (Get-Content Directory.Build.props) | % { + $m = [regex]::match($_, '(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?'); + if(!$m.Success -or $m.Groups[4].Success -or $m.Groups[5].Success) { $_; } + else { $_ -replace $m.Value, ("{0}.{1}.{2}-pre${{ github.run_number }}" -f $m.Groups[1].Value,$m.Groups[2].Value,([convert]::ToInt32($m.Groups[3].Value)+1)); } + } | Set-Content Directory.Build.props + + - name: NuGet restore + run: nuget restore LibreHardwareMonitor.sln + + - name: Build + run: msbuild LibreHardwareMonitor.sln -p:Configuration=Release -m + + - name: Publish net472 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitor-net472 + path: | + bin/Release/net472 + + - name: Publish netstandard20 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-netstandard20 + path: | + bin/Release/netstandard2.0 + + - name: Publish net60 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-net60 + path: | + bin/Release/net6.0 + + - name: Publish net70 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-net70 + path: | + bin/Release/net7.0 + + - name: Publish nupkg + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-nupkg + path: | + bin/Release/LibreHardwareMonitorLib.*.nupkg + + - name: Publish to NuGet + run: nuget push **\*.nupkg -Source 'https://api.nuget.org/v3/index.json' -ApiKey ${{secrets.NUGET_API_KEY}} diff --git a/LibreHardwareMonitor-0.9.4/.github/workflows/pull requests.yml b/LibreHardwareMonitor-0.9.4/.github/workflows/pull requests.yml new file mode 100644 index 0000000..d54a67b --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/.github/workflows/pull requests.yml @@ -0,0 +1,71 @@ +name: pull requests + +on: + pull_request: + branches: [master] + +jobs: + build: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + - uses: nuget/setup-nuget@v2 + - uses: microsoft/setup-msbuild@v1.1 + with: + msbuild-architecture: x64 + + - uses: dorny/paths-filter@v2 + id: changes + with: + filters: | + buildprops: + - 'Directory.Build.props' + - name: Update version + if: steps.changes.outputs.buildprops == 'false' + run: | + (Get-Content Directory.Build.props) | % { + $m = [regex]::match($_, '(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?'); + if(!$m.Success -or $m.Groups[4].Success -or $m.Groups[5].Success) { $_; } + else { $_ -replace $m.Value, ("{0}.{1}.{2}-ci${{ github.run_number }}" -f $m.Groups[1].Value,$m.Groups[2].Value,([convert]::ToInt32($m.Groups[3].Value)+1)); } + } | Set-Content Directory.Build.props + + - name: NuGet restore + run: nuget restore LibreHardwareMonitor.sln + + - name: Build + run: msbuild LibreHardwareMonitor.sln -p:Configuration=Release -m + + - name: Publish net472 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitor-net472 + path: | + bin/Release/net472 + + - name: Publish netstandard20 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-netstandard20 + path: | + bin/Release/netstandard2.0 + + - name: Publish net60 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-net60 + path: | + bin/Release/net6.0 + + - name: Publish net70 + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-net70 + path: | + bin/Release/net7.0 + + - name: Publish nupkg + uses: actions/upload-artifact@v4 + with: + name: LibreHardwareMonitorLib-nupkg + path: | + bin/Release/LibreHardwareMonitorLib.*.nupkg diff --git a/LibreHardwareMonitor-0.9.4/.gitignore b/LibreHardwareMonitor-0.9.4/.gitignore new file mode 100644 index 0000000..884c3f9 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/.gitignore @@ -0,0 +1,7 @@ +*.user +*.suo +[Bb]in/ +[Oo]bj/ +.idea/ +.vs/ +packages/ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.csproj b/LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.csproj new file mode 100644 index 0000000..bc554cc --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.csproj @@ -0,0 +1,121 @@ + + + 9.0.30729 + net472 + Aga.Controls + http://sourceforge.net/projects/treeviewadv/ + Copyright © Andrey Gliznetsov 2006 - 2009 + 1.7.0.0 + 1.7.0.0 + true + ..\bin\$(Configuration)\ + + + full + TRACE;DEBUG;PERF_TEST + + + pdbonly + + + + + + + + True + True + Resources.resx + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + TreeViewAdv.cs + + + + + + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + TreeViewAdv.cs + + + + + + + + + + + \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.sln b/LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.sln new file mode 100644 index 0000000..9c7ba8c --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.sln @@ -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 diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/BitmapHelper.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/BitmapHelper.cs new file mode 100644 index 0000000..a29b1c2 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/BitmapHelper.cs @@ -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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/GifDecoder.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/GifDecoder.cs new file mode 100644 index 0000000..e611155 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/GifDecoder.cs @@ -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. + *
+ * 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
+ *    }
+ * 
+ * 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()); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/NumericTextBox.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/NumericTextBox.cs new file mode 100644 index 0000000..0dcef4a --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/NumericTextBox.cs @@ -0,0 +1,189 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Globalization; + + +namespace Aga.Controls +{ + /// + /// 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 + /// + public class NumericTextBox : TextBox + { + private const int WM_PASTE = 0x302; + private NumberStyles numberStyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign; + + /// + /// Restricts the entry of characters to digits, the negative sign, + /// the decimal point, and editing keystrokes (backspace). + /// It does not handle the AltGr key + /// + /// + protected override void OnKeyPress(KeyPressEventArgs e) + { + base.OnKeyPress(e); + + e.Handled = invalidNumeric(e.KeyChar); + } + + + /// + /// Main method for verifying allowed keypresses. + /// This does not catch cut paste copy ... operations. + /// + /// + /// + 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; + } + + + /// + /// Method invoked when Windows sends a message. + /// + /// Message from Windows. + /// + /// 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. + /// + 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; } + } + + } + +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/PerformanceAnalyzer.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/PerformanceAnalyzer.cs new file mode 100644 index 0000000..94fdd6e --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/PerformanceAnalyzer.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; + +namespace Aga.Controls +{ + /// + /// Is used to analyze code performance + /// + 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 _performances = new Dictionary(); + + public static IEnumerable 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(); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Properties/Resources.Designer.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Properties/Resources.Designer.cs new file mode 100644 index 0000000..a1aaf8c --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Properties/Resources.Designer.cs @@ -0,0 +1,133 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace Aga.Controls.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [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)); + } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Properties/Resources.resx b/LibreHardwareMonitor-0.9.4/Aga.Controls/Properties/Resources.resx new file mode 100644 index 0000000..a23f6cc --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Properties/Resources.resx @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\check.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\DVSplit.cur;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Folder.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\FolderClosed.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Leaf.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\loading_icon;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\minus.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\plus.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\uncheck.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\unknown.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/ResourceHelper.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/ResourceHelper.cs new file mode 100644 index 0000000..6f865e0 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/ResourceHelper.cs @@ -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; } + } + + /// + /// Help function to convert byte[] from resource into Cursor Type + /// + /// + /// + private static Cursor GetCursor(byte[] data) + { + using (MemoryStream s = new MemoryStream(data)) + return new Cursor(s); + } + + /// + /// Help function to convert byte[] from resource into GifDecoder Type + /// + /// + /// + private static GifDecoder GetGifDecoder(byte[] data) + { + using(MemoryStream ms = new MemoryStream(data)) + return new GifDecoder(ms, true); + } + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/DVSplit.cur b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/DVSplit.cur new file mode 100644 index 0000000..2e25be2 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/DVSplit.cur differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Folder.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Folder.bmp new file mode 100644 index 0000000..f515f9e Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Folder.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/FolderClosed.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/FolderClosed.bmp new file mode 100644 index 0000000..7e848d4 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/FolderClosed.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Leaf.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Leaf.bmp new file mode 100644 index 0000000..79254b2 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Leaf.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/check.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/check.bmp new file mode 100644 index 0000000..11c9cfa Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/check.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/loading_icon b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/loading_icon new file mode 100644 index 0000000..ca716ed Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/loading_icon differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/minus.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/minus.bmp new file mode 100644 index 0000000..c6539d9 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/minus.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/plus.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/plus.bmp new file mode 100644 index 0000000..d54ab87 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/plus.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/uncheck.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/uncheck.bmp new file mode 100644 index 0000000..673b1ba Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/uncheck.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/unknown.bmp b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/unknown.bmp new file mode 100644 index 0000000..ed34bd4 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/unknown.bmp differ diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/StringCollectionEditor.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/StringCollectionEditor.cs new file mode 100644 index 0000000..411fa49 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/StringCollectionEditor.cs @@ -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 ""; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/TextHelper.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/TextHelper.cs new file mode 100644 index 0000000..10b7475 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/TextHelper.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/AbortableThreadPool.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/AbortableThreadPool.cs new file mode 100644 index 0000000..5424e89 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/AbortableThreadPool.cs @@ -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 _callbacks = new LinkedList(); + private Dictionary _threads = new Dictionary(); + + 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 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(); + } + } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/WorkItem.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/WorkItem.cs new file mode 100644 index 0000000..0bcaf4c --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/WorkItem.cs @@ -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; + } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/WorkItemStatus.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/WorkItemStatus.cs new file mode 100644 index 0000000..ec4becb --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Threading/WorkItemStatus.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Aga.Controls.Threading +{ + public enum WorkItemStatus + { + Completed, + Queued, + Executing, + Aborted + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/TimeCounter.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/TimeCounter.cs new file mode 100644 index 0000000..e06c180 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/TimeCounter.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Diagnostics.CodeAnalysis; + +namespace Aga.Controls +{ + /// + /// High resolution timer, used to test performance + /// + public static class TimeCounter + { + private static Int64 _start; + + /// + /// Start time counting + /// + public static void Start() + { + _start = 0; + QueryPerformanceCounter(ref _start); + } + + public static Int64 GetStartValue() + { + Int64 t = 0; + QueryPerformanceCounter(ref t); + return t; + } + + /// + /// Finish time counting + /// + /// time in seconds elapsed from Start till Finish + 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); + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/AutoRowHeightLayout.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/AutoRowHeightLayout.cs new file mode 100644 index 0000000..953df02 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/AutoRowHeightLayout.cs @@ -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 _rowCache; + + public AutoRowHeightLayout(TreeViewAdv treeView, int rowHeight) + { + _rowCache = new List(); + _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(); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ClassDiagram.cd b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ClassDiagram.cd new file mode 100644 index 0000000..1a44c01 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ClassDiagram.cd @@ -0,0 +1,84 @@ + + + + + + + Tree\TreeModel.cs + AAAkgAAAAAAQAGQAAAAAEAAAEAACQAAAUAAAAAAAAQE= + + + + + + + + + + + + Tree\TreePath.cs + GABAAAAAAAACAAAAAAIAAAAAAAAACAAAAAAAAAAAAAA= + + + + + + + + + + + Tree\Node.cs + AAAgABAAgCAAAAAAAgAEVAAQAAAQAAAIAAsgCAAAAAA= + + + + + + + + + + Tree\Node.cs + + + + + + + + Tree\NodeControls\NodeControl.cs + AAAAAAAAgAAAgsIAAAhAQAAwAAAAEAAAAEAIAAAAAAA= + + + + + + + + Tree\ITreeModel.cs + AAAEAAAAAAAAAEQAAAAAEAAAEAAAQAAAAAAAAAAAAAA= + + + + + + Tree\IToolTipProvider.cs + AAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ColumnCollection.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ColumnCollection.cs new file mode 100644 index 0000000..b5c6aff --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ColumnCollection.cs @@ -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 + { + public int TotalWidth + { + get + { + int res = 0; + foreach (Column c in Items) + res += c.Width; + return res; + } + } + }*/ +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DrawContext.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DrawContext.cs new file mode 100644 index 0000000..4fe8b1d --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DrawContext.cs @@ -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; } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DropNodeValidatingEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DropNodeValidatingEventArgs.cs new file mode 100644 index 0000000..fb7ef00 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DropNodeValidatingEventArgs.cs @@ -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; } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DropPosition.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DropPosition.cs new file mode 100644 index 0000000..7356326 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DropPosition.cs @@ -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; } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/EditorContext.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/EditorContext.cs new file mode 100644 index 0000000..ffea2fa --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/EditorContext.cs @@ -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; } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Enums.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Enums.cs new file mode 100644 index 0000000..3a83e9a --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Enums.cs @@ -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 + { + /// + /// Don't scale + /// + Clip, + /// + /// Scales image to fit the display rectangle, aspect ratio is not fixed. + /// + Fit, + /// + /// Scales image down if it is larger than display rectangle, taking aspect ratio into account + /// + ScaleDown, + /// + /// Scales image up if it is smaller than display rectangle, taking aspect ratio into account + /// + ScaleUp, + /// + /// Scales image to match the display rectangle, taking aspect ratio into account + /// + AlwaysScale, + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/FixedRowHeightLayout.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/FixedRowHeightLayout.cs new file mode 100644 index 0000000..316b3dc --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/FixedRowHeightLayout.cs @@ -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() + { + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IRowLayout.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IRowLayout.cs new file mode 100644 index 0000000..9a9018f --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IRowLayout.cs @@ -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(); + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IToolTipProvider.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IToolTipProvider.cs new file mode 100644 index 0000000..3f3e086 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IToolTipProvider.cs @@ -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); + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ITreeModel.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ITreeModel.cs new file mode 100644 index 0000000..680d255 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ITreeModel.cs @@ -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 NodesChanged; + event EventHandler NodesInserted; + event EventHandler NodesRemoved; + event EventHandler StructureChanged; + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IncrementalSearch.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IncrementalSearch.cs new file mode 100644 index 0000000..1390562 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IncrementalSearch.cs @@ -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 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 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; + } + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ClickColumnState.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ClickColumnState.cs new file mode 100644 index 0000000..12146c9 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ClickColumnState.cs @@ -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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ColumnState.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ColumnState.cs new file mode 100644 index 0000000..2b8fc7d --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ColumnState.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputState.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputState.cs new file mode 100644 index 0000000..b347d4f --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputState.cs @@ -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); + + /// + /// handle OnMouseMove event + /// + /// + /// true if event was handled and should be dispatched + public virtual bool MouseMove(MouseEventArgs args) + { + return false; + } + + public virtual void MouseDoubleClick(TreeNodeAdvMouseEventArgs args) + { + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputWithControl.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputWithControl.cs new file mode 100644 index 0000000..6559b67 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputWithControl.cs @@ -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) + { + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputWithShift.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputWithShift.cs new file mode 100644 index 0000000..777fc7a --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/InputWithShift.cs @@ -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; + } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/NormalInputState.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/NormalInputState.cs new file mode 100644 index 0000000..7a66be9 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/NormalInputState.cs @@ -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; + } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ReorderColumnState.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ReorderColumnState.cs new file mode 100644 index 0000000..181cca5 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ReorderColumnState.cs @@ -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); + } + } + } +} \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ResizeColumnState.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ResizeColumnState.cs new file mode 100644 index 0000000..e4d8653 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Input/ResizeColumnState.cs @@ -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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ListModel.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ListModel.cs new file mode 100644 index 0000000..4d833e2 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ListModel.cs @@ -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(); + } + + 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)); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NativeMethods.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NativeMethods.cs new file mode 100644 index 0000000..81e2635 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NativeMethods.cs @@ -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); + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Node.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Node.cs new file mode 100644 index 0000000..733c089 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Node.cs @@ -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 + { + 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 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); + } + } + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControlInfo.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControlInfo.cs new file mode 100644 index 0000000..c884a26 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControlInfo.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/BaseTextControl.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/BaseTextControl.cs new file mode 100644 index 0000000..20e5f84 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/BaseTextControl.cs @@ -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 _brushes = new Dictionary(); + 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(); + } + } + + /// + /// Fires when control is going to draw a text. Can be used to change text or back color + /// + public event EventHandler 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()); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/BindableControl.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/BindableControl.cs new file mode 100644 index 0000000..673d8fc --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/BindableControl.cs @@ -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 ValueNeeded; + private void OnValueNeeded(NodeControlValueEventArgs args) + { + if (ValueNeeded != null) + ValueNeeded(this, args); + } + + public event EventHandler ValuePushed; + private void OnValuePushed(NodeControlValueEventArgs args) + { + if (ValuePushed != null) + ValuePushed(this, args); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/ClassDiagram.cd b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/ClassDiagram.cd new file mode 100644 index 0000000..733d539 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/ClassDiagram.cd @@ -0,0 +1,105 @@ + + + + + + + Tree\NodeControls\NodeStateIcon.cs + ABAAAAAAAAQAQAAAAAAAAAAAAAAAAAAAQIAAAAAAAAA= + + + + + + Tree\NodeControls\BindableControl.cs + FAAAAAAQIBAQCgAEAAAAIAAAAAAAAAEMAAACAAAAAAE= + + + + + + Tree\NodeControls\NodeCheckBox.cs + AAEAAAAAAAACgkQCAAAAAAigAgAAEGABAAAIAAAAAAA= + + + + + + Tree\NodeControls\NodeControl.cs + AAAAAJAAgIgBkkoQAAgAQAAwAAABEIQAAEBIAAAAAAA= + + + + + + + + + Tree\NodeControls\NodeIcon.cs + ABAAAAAAAAAAAgAAAAAAAAAgAAAAAAAAAAAAAAAAAAA= + + + + + + Tree\NodeControls\NodePlusMinus.cs + AAAAAAAAAAAAAgAAAAAAAEAgAAAAMCAAAAAIACAAAAA= + + + + + + Tree\NodeControls\BaseTextControl.cs + AAAAICBQACAAIgACBCAEAQA8AgmFoAAwAAAAACACAMA= + + + + + + Tree\NodeControls\NodeTextBox.cs + QQQAhAAAADAMgAAAABAAAAAAAgEAIAAAAAAAAIAAAAA= + + + + + + Tree\NodeControls\EditableControl.cs + QQAgAAAACGgkAMAABAEEkADAEAAUEAAABAGoAAAAAQA= + + + + + + Tree\NodeControls\NodeComboBox.cs + wQACAAAAAAAMAEBAAAAAAABAAAAAAAABAAAAAAAAAAA= + + + + + + Tree\NodeControls\NodeNumericUpDown.cs + wQAAAACAAAAEAABAIAAQIAAAAAAAAAABAAAIAAAAAII= + + + + + + Tree\NodeControls\InteractiveControl.cs + AAAABAAAAAAAAAAACAAAAAAAABAAAQAAAAAAAAIAAAA= + + + + + + Tree\NodeControls\NodeDecimalTextBox.cs + AQAAAAAAAACAAAACAAAAAAQAAAAAIAAAAAgAAAAAAAA= + + + + + + Tree\NodeControls\NodeIntegerTextBox.cs + AQAAAAAAAAAAAAACAAAAAAQAAAAAIAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/DrawEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/DrawEventArgs.cs new file mode 100644 index 0000000..8333c1f --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/DrawEventArgs.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/EditEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/EditEventArgs.cs new file mode 100644 index 0000000..d26033b --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/EditEventArgs.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/EditableControl.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/EditableControl.cs new file mode 100644 index 0000000..ec2a9d9 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/EditableControl.cs @@ -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 + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/ExpandingIcon.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/ExpandingIcon.cs new file mode 100644 index 0000000..bd2c34c --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/ExpandingIcon.cs @@ -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 +{ + /// + /// Displays an animated icon for those nodes, who are in expanding state. + /// Parent TreeView must have AsyncExpanding property set to true. + /// + 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; + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/InteractiveControl.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/InteractiveControl.cs new file mode 100644 index 0000000..0a9f803 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/InteractiveControl.cs @@ -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 IsEditEnabledValueNeeded; + private void OnIsEditEnabledValueNeeded(NodeControlValueEventArgs args) + { + if (IsEditEnabledValueNeeded != null) + IsEditEnabledValueNeeded(this, args); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/LabelEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/LabelEventArgs.cs new file mode 100644 index 0000000..d792253 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/LabelEventArgs.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeCheckBox.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeCheckBox.cs new file mode 100644 index 0000000..dbfb3cb --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeCheckBox.cs @@ -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 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)); + } + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeComboBox.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeComboBox.cs new file mode 100644 index 0000000..8aff375 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeComboBox.cs @@ -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 _dropDownItems; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")] + [Editor(typeof(StringCollectionEditor), typeof(UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public List DropDownItems + { + get { return _dropDownItems; } + } + + #endregion + + public event EventHandler CreatingEditor; + + public NodeComboBox() + { + _dropDownItems = new List(); + } + + 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 list = new List(); + 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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControl.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControl.cs new file mode 100644 index 0000000..9243e61 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControl.cs @@ -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 IsVisibleValueNeeded; + protected virtual void OnIsVisibleValueNeeded(NodeControlValueEventArgs args) + { + if (IsVisibleValueNeeded != null) + IsVisibleValueNeeded(this, args); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControlValueEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControlValueEventArgs.cs new file mode 100644 index 0000000..3686440 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControlValueEventArgs.cs @@ -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) + { + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControlsCollection.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControlsCollection.cs new file mode 100644 index 0000000..f31e05e --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeControlsCollection.cs @@ -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 + { + 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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeDecimalTextBox.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeDecimalTextBox.cs new file mode 100644 index 0000000..20ada8e --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeDecimalTextBox.cs @@ -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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeEventArgs.cs new file mode 100644 index 0000000..cedccbf --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeEventArgs.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeIcon.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeIcon.cs new file mode 100644 index 0000000..d86340c --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeIcon.cs @@ -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; } + } + + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeIntegerTextBox.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeIntegerTextBox.cs new file mode 100644 index 0000000..7e6d075 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeIntegerTextBox.cs @@ -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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeNumericUpDown.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeNumericUpDown.cs new file mode 100644 index 0000000..743e6f7 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeNumericUpDown.cs @@ -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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodePlusMinus.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodePlusMinus.cs new file mode 100644 index 0000000..209f5d8 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodePlusMinus.cs @@ -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 + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeStateIcon.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeStateIcon.cs new file mode 100644 index 0000000..bd041e8 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeStateIcon.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeTextBox.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeTextBox.cs new file mode 100644 index 0000000..81065d8 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/NodeControls/NodeTextBox.cs @@ -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 LabelChanged; + protected void OnLabelChanged(object subject, string oldLabel, string newLabel) + { + if (LabelChanged != null) + LabelChanged(this, new LabelEventArgs(subject, oldLabel, newLabel)); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/SortedTreeModel.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/SortedTreeModel.cs new file mode 100644 index 0000000..96f22c2 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/SortedTreeModel.cs @@ -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(_innerModel_NodesChanged); + _innerModel.NodesInserted += new EventHandler(_innerModel_NodesInserted); + _innerModel.NodesRemoved += new EventHandler(_innerModel_NodesRemoved); + _innerModel.StructureChanged += new EventHandler(_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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumn.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumn.cs new file mode 100644 index 0000000..1dff0d7 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumn.cs @@ -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 + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumnCollection.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumnCollection.cs new file mode 100644 index 0000000..2368ec6 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumnCollection.cs @@ -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 + { + 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(); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumnEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumnEventArgs.cs new file mode 100644 index 0000000..405c707 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumnEventArgs.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeListAdapter.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeListAdapter.cs new file mode 100644 index 0000000..819e568 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeListAdapter.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Aga.Controls.Tree +{ + /// + /// Converts IEnumerable interface to ITreeModel. + /// Allows to display a plain list in the TreeView + /// + 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 NodesChanged; + public void OnNodesChanged(TreeModelEventArgs args) + { + if (NodesChanged != null) + NodesChanged(this, args); + } + + public event EventHandler StructureChanged; + public void OnStructureChanged(TreePathEventArgs args) + { + if (StructureChanged != null) + StructureChanged(this, args); + } + + public event EventHandler NodesInserted; + public void OnNodeInserted(TreeModelEventArgs args) + { + if (NodesInserted != null) + NodesInserted(this, args); + } + + public event EventHandler NodesRemoved; + public void OnNodeRemoved(TreeModelEventArgs args) + { + if (NodesRemoved != null) + NodesRemoved(this, args); + } + + #endregion + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModel.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModel.cs new file mode 100644 index 0000000..14ef857 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModel.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; + +namespace Aga.Controls.Tree +{ + /// + /// Provides a simple ready to use implementation of . Warning: this class is not optimized + /// to work with big amount of data. In this case create you own implementation of ITreeModel, and pay attention + /// on GetChildren and IsLeaf methods. + /// + public class TreeModel : ITreeModel + { + private Node _root; + public Node Root + { + get { return _root; } + } + + public Collection 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 stack = new Stack(); + 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 NodesChanged; + internal void OnNodesChanged(TreeModelEventArgs args) + { + if (NodesChanged != null) + NodesChanged(this, args); + } + + public event EventHandler StructureChanged; + public void OnStructureChanged(TreePathEventArgs args) + { + if (StructureChanged != null) + StructureChanged(this, args); + } + + public event EventHandler 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 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 + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModelBase.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModelBase.cs new file mode 100644 index 0000000..a366295 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModelBase.cs @@ -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 NodesChanged; + protected void OnNodesChanged(TreeModelEventArgs args) + { + if (NodesChanged != null) + NodesChanged(this, args); + } + + public event EventHandler StructureChanged; + protected void OnStructureChanged(TreePathEventArgs args) + { + if (StructureChanged != null) + StructureChanged(this, args); + } + + public event EventHandler NodesInserted; + protected void OnNodesInserted(TreeModelEventArgs args) + { + if (NodesInserted != null) + NodesInserted(this, args); + } + + public event EventHandler NodesRemoved; + protected void OnNodesRemoved(TreeModelEventArgs args) + { + if (NodesRemoved != null) + NodesRemoved(this, args); + } + + public virtual void Refresh() + { + OnStructureChanged(new TreePathEventArgs(TreePath.Empty)); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModelEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModelEventArgs.cs new file mode 100644 index 0000000..5148e63 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModelEventArgs.cs @@ -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; } + } + + /// + /// + /// + /// Path to a parent node + /// Child nodes + public TreeModelEventArgs(TreePath parent, object[] children) + : this(parent, null, children) + { + } + + /// + /// + /// + /// Path to a parent node + /// Indices of children in parent nodes collection + /// Child nodes + 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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeNodeAdv.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeNodeAdv.cs new file mode 100644 index 0000000..c2c6668 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeNodeAdv.cs @@ -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 + { + 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 Collapsing; + internal void OnCollapsing() + { + if (Collapsing != null) + Collapsing(this, new TreeViewAdvEventArgs(this)); + } + + public event EventHandler Collapsed; + internal void OnCollapsed() + { + if (Collapsed != null) + Collapsed(this, new TreeViewAdvEventArgs(this)); + } + + public event EventHandler Expanding; + internal void OnExpanding() + { + if (Expanding != null) + Expanding(this, new TreeViewAdvEventArgs(this)); + } + + public event EventHandler 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; + } + } + } + + /// + /// Returns true if all parent nodes of this node are expanded. + /// + 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 _nodes; + internal Collection Nodes + { + get { return _nodes; } + } + + private ReadOnlyCollection _children; + public ReadOnlyCollection 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(_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 + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeNodeAdvMouseEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeNodeAdvMouseEventArgs.cs new file mode 100644 index 0000000..145c5b8 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeNodeAdvMouseEventArgs.cs @@ -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) + { + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreePath.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreePath.cs new file mode 100644 index 0000000..4b923ff --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreePath.cs @@ -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); + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreePathEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreePathEventArgs.cs new file mode 100644 index 0000000..6ee8a4d --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreePathEventArgs.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Designer.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Designer.cs new file mode 100644 index 0000000..b08e641 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Designer.cs @@ -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; + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Draw.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Draw.cs new file mode 100644 index 0000000..60f8662 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Draw.cs @@ -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 + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Editor.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Editor.cs new file mode 100644 index 0000000..b65aca0 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Editor.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Input.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Input.cs new file mode 100644 index 0000000..57d1ecf --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Input.cs @@ -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 + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Properties.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Properties.cs new file mode 100644 index 0000000..6d042d0 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Properties.cs @@ -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; + } + } + + /// + /// returns all nodes, which parent is expanded + /// + private IEnumerable 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 _rowMap; + internal List 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; } + } + + + /// + /// Number of rows fits to the current page + /// + internal int CurrentPageSize + { + get + { + return _rowLayout.CurrentPageSize; + } + } + + /// + /// Number of all visible nodes (which parent is expanded) + /// + 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 _selection; + internal List 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; + /// + /// The model associated with this . + /// + /// + /// + [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; + /// + /// The font to render content in. + /// + [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; + /// + /// Set to true to expand each row's height to fit the text of it's largest column. + /// + [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 Columns + { + get { return _columns; } + } + + private NodeControlsCollection _controls; + [Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Editor(typeof(NodeControlCollectionEditor), typeof(UITypeEditor))] + public Collection NodeControls + { + get + { + return _controls; + } + } + + private bool _asyncExpanding; + /// + /// When set to true, node contents will be read in background thread. + /// + [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 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 _readonlySelection; + [Browsable(false)] + public ReadOnlyCollection 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; } + } + + /// + /// Indicates the distance the content is scrolled to the left + /// + [Browsable(false)] + public int HorizontalScrollPosition + { + get + { + if (_hScrollBar.Visible) + return _hScrollBar.Value; + else + return 0; + } + } + + #endregion + + #endregion + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.cs new file mode 100644 index 0000000..d149106 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.cs @@ -0,0 +1,1254 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Drawing; +using System.Security.Permissions; +using System.Threading; +using System.Windows.Forms; +using System.Collections; + +using Aga.Controls.Tree.NodeControls; +using Aga.Controls.Threading; + + +namespace Aga.Controls.Tree +{ + /// + /// Extensible advanced implemented in 100% managed C# code. + /// Features: Model/View architecture. Multiple column per node. Ability to select + /// multiple tree nodes. Different types of controls for each node column: + /// , Icon, Label... Drag and Drop highlighting. Load on + /// demand of nodes. Incremental search of nodes. + /// + public partial class TreeViewAdv : Control + { + public static Action CustomCheckRenderFunc; + public static Action CustomColumnBackgroundRenderFunc; + public static Action CustomColumnTextRenderFunc; + public static Color CustomSelectedTextColor = SystemColors.ControlText; + public static Pen CustomHorizontalLinePen = new Pen(Color.FromArgb(247, 247, 247)); + public static Action CustomPlusMinusRenderFunc; + public static Brush CustomSelectedRowBrush = new SolidBrush(Color.FromArgb(240, 240, 240)); + + private const int LeftMargin = 7; + internal const int ItemDragSensivity = 4; + private readonly int _columnHeaderHeight; + private const int DividerWidth = 9; + private const int DividerCorrectionGap = -2; + + private Pen _linePen; + private Pen _markPen; + private bool _suspendUpdate; + private bool _needFullUpdate; + private bool _fireSelectionEvent; + private NodePlusMinus _plusMinus; + private ToolTip _toolTip; + private DrawContext _measureContext; + private TreeColumn _hotColumn; + private IncrementalSearch _search; + private List _expandingNodes = new List(); + private AbortableThreadPool _threadPool = new AbortableThreadPool(); + + private float dpiX; + private float dpiY; + private float dpiXscale = 1; + private float dpiYscale = 1; + + #region Public Events + + [Category("Action")] + public event ItemDragEventHandler ItemDrag; + private void OnItemDrag(MouseButtons buttons, object item) + { + if (ItemDrag != null) + ItemDrag(this, new ItemDragEventArgs(buttons, item)); + } + + [Category("Behavior")] + public event EventHandler NodeMouseClick; + private void OnNodeMouseClick(TreeNodeAdvMouseEventArgs args) + { + if (NodeMouseClick != null) + NodeMouseClick(this, args); + } + + [Category("Behavior")] + public event EventHandler NodeMouseDoubleClick; + private void OnNodeMouseDoubleClick(TreeNodeAdvMouseEventArgs args) + { + if (NodeMouseDoubleClick != null) + NodeMouseDoubleClick(this, args); + } + + [Category("Behavior")] + public event EventHandler ColumnWidthChanged; + internal void OnColumnWidthChanged(TreeColumn column) + { + if (ColumnWidthChanged != null) + ColumnWidthChanged(this, new TreeColumnEventArgs(column)); + } + + [Category("Behavior")] + public event EventHandler ColumnReordered; + internal void OnColumnReordered(TreeColumn column) + { + if (ColumnReordered != null) + ColumnReordered(this, new TreeColumnEventArgs(column)); + } + + [Category("Behavior")] + public event EventHandler ColumnClicked; + internal void OnColumnClicked(TreeColumn column) + { + if (ColumnClicked != null) + ColumnClicked(this, new TreeColumnEventArgs(column)); + } + + [Category("Behavior")] + public event EventHandler SelectionChanged; + internal void OnSelectionChanged() + { + if (SuspendSelectionEvent) + _fireSelectionEvent = true; + else + { + _fireSelectionEvent = false; + if (SelectionChanged != null) + SelectionChanged(this, EventArgs.Empty); + } + } + + [Category("Behavior")] + public event EventHandler Collapsing; + private void OnCollapsing(TreeNodeAdv node) + { + if (Collapsing != null) + Collapsing(this, new TreeViewAdvEventArgs(node)); + } + + [Category("Behavior")] + public event EventHandler Collapsed; + private void OnCollapsed(TreeNodeAdv node) + { + if (Collapsed != null) + Collapsed(this, new TreeViewAdvEventArgs(node)); + } + + [Category("Behavior")] + public event EventHandler Expanding; + private void OnExpanding(TreeNodeAdv node) + { + if (Expanding != null) + Expanding(this, new TreeViewAdvEventArgs(node)); + } + + [Category("Behavior")] + public event EventHandler Expanded; + private void OnExpanded(TreeNodeAdv node) + { + if (Expanded != null) + Expanded(this, new TreeViewAdvEventArgs(node)); + } + + [Category("Behavior")] + public event EventHandler GridLineStyleChanged; + private void OnGridLineStyleChanged() + { + if (GridLineStyleChanged != null) + GridLineStyleChanged(this, EventArgs.Empty); + } + + [Category("Behavior")] + public event ScrollEventHandler Scroll; + protected virtual void OnScroll(ScrollEventArgs e) + { + if (Scroll != null) + Scroll(this, e); + } + + [Category("Behavior")] + public event EventHandler RowDraw; + protected virtual void OnRowDraw(PaintEventArgs e, TreeNodeAdv node, DrawContext context, int row, Rectangle rowRect) + { + if (RowDraw != null) + { + TreeViewRowDrawEventArgs args = new TreeViewRowDrawEventArgs(e.Graphics, e.ClipRectangle, node, context, row, rowRect); + RowDraw(this, args); + } + } + + /// + /// Fires when control is going to draw. Can be used to change text or back color + /// + [Category("Behavior")] + public event EventHandler DrawControl; + + internal bool DrawControlMustBeFired() + { + return DrawControl != null; + } + + internal void FireDrawControl(DrawEventArgs args) + { + OnDrawControl(args); + } + + protected virtual void OnDrawControl(DrawEventArgs args) + { + if (DrawControl != null) + DrawControl(this, args); + } + + + [Category("Drag Drop")] + public event EventHandler DropNodeValidating; + protected virtual void OnDropNodeValidating(Point point, ref TreeNodeAdv node) + { + if (DropNodeValidating != null) + { + DropNodeValidatingEventArgs args = new DropNodeValidatingEventArgs(point, node); + DropNodeValidating(this, args); + node = args.Node; + } + } + #endregion + + public TreeViewAdv() + { + InitializeComponent(); + SetDPI(); + SetStyle(ControlStyles.AllPaintingInWmPaint + | ControlStyles.UserPaint + | ControlStyles.OptimizedDoubleBuffer + | ControlStyles.ResizeRedraw + | ControlStyles.Selectable + , true); + + + if (Application.RenderWithVisualStyles) + _columnHeaderHeight = 20; + else + _columnHeaderHeight = 17; + _columnHeaderHeight = GetScaledSize(_columnHeaderHeight); + + //BorderStyle = BorderStyle.Fixed3D; + _hScrollBar.Height = SystemInformation.HorizontalScrollBarHeight; + _vScrollBar.Width = SystemInformation.VerticalScrollBarWidth; + _rowLayout = new FixedRowHeightLayout(this, RowHeight); + _rowMap = new List(); + _selection = new List(); + _readonlySelection = new ReadOnlyCollection(_selection); + _columns = new TreeColumnCollection(this); + _toolTip = new ToolTip(); + + _measureContext = new DrawContext(); + _measureContext.Font = Font; + _measureContext.Graphics = Graphics.FromImage(new Bitmap(1, 1)); + + Input = new NormalInputState(this); + _search = new IncrementalSearch(this); + CreateNodes(); + CreatePens(); + + ArrangeControls(); + + _plusMinus = new NodePlusMinus(); + _controls = new NodeControlsCollection(this); + + Font = _font; + ExpandingIcon.IconChanged += ExpandingIconChanged; + + BackColor = Color.Black; + } + + public void SetDPI() + { + // https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266(v=vs.85).aspx + const int _default_dpi = 96; + Graphics g = this.CreateGraphics(); + + try + { + this.dpiX = g.DpiX; + this.dpiY = g.DpiY; + } + finally + { + g.Dispose(); + } + if (dpiX > 0) + { + this.dpiXscale = dpiX / _default_dpi; + } + if (dpiY > 0) + { + this.dpiYscale = dpiY / _default_dpi; + } + } + + public int GetScaledSize(int size, bool useY = true) + { + int scaledsize = size; + + if (useY && this.dpiYscale > 1) + { + scaledsize = (int)(this.dpiYscale * size); + } + else if (this.dpiXscale > 1) + { + scaledsize = (int)(this.dpiXscale * size); + } + return scaledsize; + } + + void ExpandingIconChanged(object sender, EventArgs e) + { + if (IsHandleCreated && !IsDisposed) + BeginInvoke(new MethodInvoker(DrawIcons)); + } + + private void DrawIcons() + { + using (Graphics gr = Graphics.FromHwnd(this.Handle)) + { + //Apply the same Graphics Transform logic as used in OnPaint. + int y = 0; + if (UseColumns) + { + y += ColumnHeaderHeight; + if (Columns.Count == 0) + return; + } + int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y; + y -= firstRowY; + gr.ResetTransform(); + gr.TranslateTransform(-OffsetX, y); + + DrawContext context = new DrawContext(); + context.Graphics = gr; + for (int i = 0; i < _expandingNodes.Count; i++) + { + foreach (NodeControlInfo item in GetNodeControls(_expandingNodes[i])) + { + if (item.Control is ExpandingIcon) + { + Rectangle bounds = item.Bounds; + if (item.Node.Parent == null && UseColumns) + bounds.Location = Point.Empty; // display root expanding icon at 0,0 + + context.Bounds = bounds; + item.Control.Draw(item.Node, context); + } + } + } + } + } + + #region Public Methods + + public TreePath GetPath(TreeNodeAdv node) + { + if (node == _root) + return TreePath.Empty; + else + { + Stack stack = new Stack(); + while (node != _root && node != null) + { + stack.Push(node.Tag); + node = node.Parent; + } + return new TreePath(stack.ToArray()); + } + } + + public TreeNodeAdv GetNodeAt(Point point) + { + NodeControlInfo info = GetNodeControlInfoAt(point); + return info.Node; + } + + public NodeControlInfo GetNodeControlInfoAt(Point point) + { + if (point.X < 0 || point.Y < 0) + return NodeControlInfo.Empty; + + int row = _rowLayout.GetRowAt(point); + if (row < RowCount && row >= 0) + return GetNodeControlInfoAt(RowMap[row], point); + else + return NodeControlInfo.Empty; + } + + private NodeControlInfo GetNodeControlInfoAt(TreeNodeAdv node, Point point) + { + Rectangle rect = _rowLayout.GetRowBounds(FirstVisibleRow); + point.Y += (rect.Y - ColumnHeaderHeight); + point.X += OffsetX; + foreach (NodeControlInfo info in GetNodeControls(node)) + if (info.Bounds.Contains(point)) + return info; + + if (FullRowSelect) + return new NodeControlInfo(null, Rectangle.Empty, node); + else + return NodeControlInfo.Empty; + } + + public void BeginUpdate() + { + _suspendUpdate = true; + SuspendSelectionEvent = true; + } + + public void EndUpdate() + { + _suspendUpdate = false; + if (_needFullUpdate) + FullUpdate(); + else + UpdateView(); + SuspendSelectionEvent = false; + } + + public void ExpandAll() + { + _root.ExpandAll(); + } + + public void CollapseAll() + { + _root.CollapseAll(); + } + + /// + /// Expand all parent nodes, and scroll to the specified node + /// + public void EnsureVisible(TreeNodeAdv node) + { + if (node == null) + throw new ArgumentNullException("node"); + + if (!IsMyNode(node)) + throw new ArgumentException(); + + TreeNodeAdv parent = node.Parent; + while (parent != _root) + { + parent.IsExpanded = true; + parent = parent.Parent; + } + ScrollTo(node); + } + + /// + /// Make node visible, scroll if needed. All parent nodes of the specified node must be expanded + /// + /// + public void ScrollTo(TreeNodeAdv node) + { + if (node == null) + throw new ArgumentNullException("node"); + + if (!IsMyNode(node)) + throw new ArgumentException(); + + if (node.Row < 0) + CreateRowMap(); + + int row = -1; + + if (node.Row < FirstVisibleRow) + row = node.Row; + else + { + int pageStart = _rowLayout.GetRowBounds(FirstVisibleRow).Top; + int rowBottom = _rowLayout.GetRowBounds(node.Row).Bottom; + if (rowBottom > pageStart + DisplayRectangle.Height - ColumnHeaderHeight) + row = _rowLayout.GetFirstRow(node.Row); + } + + if (row >= _vScrollBar.Minimum && row <= _vScrollBar.Maximum) + _vScrollBar.Value = row; + } + + public void ClearSelection() + { + BeginUpdate(); + try + { + ClearSelectionInternal(); + } + finally + { + EndUpdate(); + } + } + + internal void ClearSelectionInternal() + { + while (Selection.Count > 0) + { + var t = Selection[0]; + t.IsSelected = false; + Selection.Remove(t); //hack + } + } + + #endregion + + protected override void OnSizeChanged(EventArgs e) + { + ArrangeControls(); + SafeUpdateScrollBars(); + base.OnSizeChanged(e); + } + + private void ArrangeControls() + { + int hBarSize = _hScrollBar.Height; + int vBarSize = _vScrollBar.Width; + Rectangle clientRect = ClientRectangle; + + _hScrollBar.SetBounds(clientRect.X, clientRect.Bottom - hBarSize, + clientRect.Width - vBarSize, hBarSize); + + _vScrollBar.SetBounds(clientRect.Right - vBarSize, clientRect.Y, + vBarSize, clientRect.Height - hBarSize); + } + + private void SafeUpdateScrollBars() + { + if (InvokeRequired) + BeginInvoke(new MethodInvoker(UpdateScrollBars)); + else + UpdateScrollBars(); + } + + private void UpdateScrollBars() + { + UpdateVScrollBar(); + UpdateHScrollBar(); + UpdateVScrollBar(); + UpdateHScrollBar(); + _hScrollBar.Width = DisplayRectangle.Width; + _vScrollBar.Height = DisplayRectangle.Height; + } + + private void UpdateHScrollBar() + { + _hScrollBar.Maximum = ContentWidth; + _hScrollBar.LargeChange = Math.Max(DisplayRectangle.Width, 0); + _hScrollBar.SmallChange = 5; + _hScrollBar.Visible = _hScrollBar.LargeChange < _hScrollBar.Maximum; + _hScrollBar.Value = Math.Min(_hScrollBar.Value, _hScrollBar.Maximum - _hScrollBar.LargeChange + 1); + } + + private void UpdateVScrollBar() + { + _vScrollBar.Maximum = Math.Max(RowCount - 1, 0); + _vScrollBar.LargeChange = _rowLayout.PageRowCount; + _vScrollBar.Visible = (RowCount > 0) && (_vScrollBar.LargeChange <= _vScrollBar.Maximum); + _vScrollBar.Value = Math.Min(_vScrollBar.Value, _vScrollBar.Maximum - _vScrollBar.LargeChange + 1); + } + + protected override CreateParams CreateParams + { + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + get + { + CreateParams res = base.CreateParams; + switch (BorderStyle) + { + case BorderStyle.FixedSingle: + res.Style |= 0x800000; + break; + case BorderStyle.Fixed3D: + res.ExStyle |= 0x200; + break; + } + return res; + } + } + + protected override void OnGotFocus(EventArgs e) + { + UpdateView(); + ChangeInput(); + base.OnGotFocus(e); + } + + protected override void OnFontChanged(EventArgs e) + { + base.OnFontChanged(e); + _measureContext.Font = Font; + FullUpdate(); + } + + internal IEnumerable GetNodeControls(TreeNodeAdv node) + { + if (node == null) + yield break; + Rectangle rowRect = _rowLayout.GetRowBounds(node.Row); + foreach (NodeControlInfo n in GetNodeControls(node, rowRect)) + yield return n; + } + + internal IEnumerable GetNodeControls(TreeNodeAdv node, Rectangle rowRect) + { + if (node == null) + yield break; + + int scaledIndent = node.Tree.GetScaledSize(_indent, false); + int y = rowRect.Y; + int x = (node.Level - 1) * scaledIndent + LeftMargin; + int width = 0; + if (node.Row == 0 && ShiftFirstNode) + x -= scaledIndent; + Rectangle rect = Rectangle.Empty; + + if (ShowPlusMinus) + { + width = _plusMinus.GetActualSize(node, _measureContext).Width; + rect = new Rectangle(x, y, width, rowRect.Height); + if (UseColumns && Columns.Count > 0 && Columns[0].Width < rect.Right) + rect.Width = Columns[0].Width - x; + + yield return new NodeControlInfo(_plusMinus, rect, node); + x += width; + } + + if (!UseColumns) + { + foreach (NodeControl c in NodeControls) + { + Size s = c.GetActualSize(node, _measureContext); + if (!s.IsEmpty) + { + width = s.Width; + rect = new Rectangle(x, y, width, rowRect.Height); + x += rect.Width; + yield return new NodeControlInfo(c, rect, node); + } + } + } + else + { + int right = 0; + foreach (TreeColumn col in Columns) + { + if (col.IsVisible && col.Width > 0) + { + right += col.Width; + for (int i = 0; i < NodeControls.Count; i++) + { + NodeControl nc = NodeControls[i]; + if (nc.ParentColumn == col) + { + Size s = nc.GetActualSize(node, _measureContext); + if (!s.IsEmpty) + { + bool isLastControl = true; + for (int k = i + 1; k < NodeControls.Count; k++) + if (NodeControls[k].ParentColumn == col) + { + isLastControl = false; + break; + } + + width = right - x; + if (!isLastControl) + width = s.Width; + int maxWidth = Math.Max(0, right - x); + rect = new Rectangle(x, y, Math.Min(maxWidth, width), rowRect.Height); + x += width; + yield return new NodeControlInfo(nc, rect, node); + } + } + } + x = right; + } + } + } + } + + internal static double Dist(Point p1, Point p2) + { + return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2)); + } + + public void FullUpdate() + { + HideEditor(); + if (InvokeRequired) + BeginInvoke(new MethodInvoker(UnsafeFullUpdate)); + else + UnsafeFullUpdate(); + } + + private void UnsafeFullUpdate() + { + _rowLayout.ClearCache(); + CreateRowMap(); + SafeUpdateScrollBars(); + UpdateView(); + _needFullUpdate = false; + } + + internal void UpdateView() + { + if (!_suspendUpdate) + Invalidate(false); + } + + internal void UpdateHeaders() + { + Invalidate(new Rectangle(0, 0, Width, ColumnHeaderHeight)); + } + + internal void UpdateColumns() + { + FullUpdate(); + } + + private void CreateNodes() + { + Selection.Clear(); + SelectionStart = null; + _root = new TreeNodeAdv(this, null); + _root.IsExpanded = true; + if (_root.Nodes.Count > 0) + CurrentNode = _root.Nodes[0]; + else + CurrentNode = null; + } + + internal void ReadChilds(TreeNodeAdv parentNode) + { + ReadChilds(parentNode, false); + } + + internal void ReadChilds(TreeNodeAdv parentNode, bool performFullUpdate) + { + if (!parentNode.IsLeaf) + { + parentNode.IsExpandedOnce = true; + parentNode.Nodes.Clear(); + + if (Model != null) + { + IEnumerable items = Model.GetChildren(GetPath(parentNode)); + if (items != null) + foreach (object obj in items) + { + AddNewNode(parentNode, obj, -1); + if (performFullUpdate) + FullUpdate(); + } + } + + if (parentNode.AutoExpandOnStructureChanged) + parentNode.ExpandAll(); + } + } + + private void AddNewNode(TreeNodeAdv parent, object tag, int index) + { + TreeNodeAdv node = new TreeNodeAdv(this, tag); + AddNode(parent, index, node); + } + + private void AddNode(TreeNodeAdv parent, int index, TreeNodeAdv node) + { + if (index >= 0 && index < parent.Nodes.Count) + parent.Nodes.Insert(index, node); + else + parent.Nodes.Add(node); + + node.IsLeaf = Model.IsLeaf(GetPath(node)); + if (node.IsLeaf) + node.Nodes.Clear(); + if (!LoadOnDemand || node.IsExpandedOnce) + ReadChilds(node); + } + + private struct ExpandArgs + { + public TreeNodeAdv Node; + public bool Value; + public bool IgnoreChildren; + } + + public void AbortBackgroundExpandingThreads() + { + _threadPool.CancelAll(true); + for (int i = 0; i < _expandingNodes.Count; i++) + _expandingNodes[i].IsExpandingNow = false; + _expandingNodes.Clear(); + Invalidate(); + } + + internal void SetIsExpanded(TreeNodeAdv node, bool value, bool ignoreChildren) + { + ExpandArgs eargs = new ExpandArgs(); + eargs.Node = node; + eargs.Value = value; + eargs.IgnoreChildren = ignoreChildren; + + if (AsyncExpanding && LoadOnDemand && !_threadPool.IsMyThread(Thread.CurrentThread)) + { + WaitCallback wc = delegate(object argument) { SetIsExpanded((ExpandArgs)argument); }; + _threadPool.QueueUserWorkItem(wc, eargs); + } + else + SetIsExpanded(eargs); + } + + private void SetIsExpanded(ExpandArgs eargs) + { + bool update = !eargs.IgnoreChildren && !AsyncExpanding; + if (update) + BeginUpdate(); + try + { + if (IsMyNode(eargs.Node) && eargs.Node.IsExpanded != eargs.Value) + SetIsExpanded(eargs.Node, eargs.Value); + + if (!eargs.IgnoreChildren) + SetIsExpandedRecursive(eargs.Node, eargs.Value); + } + finally + { + if (update) + EndUpdate(); + } + } + + internal void SetIsExpanded(TreeNodeAdv node, bool value) + { + if (Root == node && !value) + return; //Can't collapse root node + + if (value) + { + OnExpanding(node); + node.OnExpanding(); + } + else + { + OnCollapsing(node); + node.OnCollapsing(); + } + + if (value && !node.IsExpandedOnce) + { + if (AsyncExpanding && LoadOnDemand) + { + AddExpandingNode(node); + node.AssignIsExpanded(true); + Invalidate(); + } + ReadChilds(node, AsyncExpanding); + RemoveExpandingNode(node); + } + node.AssignIsExpanded(value); + SmartFullUpdate(); + + if (value) + { + OnExpanded(node); + node.OnExpanded(); + } + else + { + OnCollapsed(node); + node.OnCollapsed(); + } + } + + private void RemoveExpandingNode(TreeNodeAdv node) + { + node.IsExpandingNow = false; + _expandingNodes.Remove(node); + if (_expandingNodes.Count <= 0) + ExpandingIcon.Stop(); + } + + private void AddExpandingNode(TreeNodeAdv node) + { + node.IsExpandingNow = true; + _expandingNodes.Add(node); + ExpandingIcon.Start(); + } + + internal void SetIsExpandedRecursive(TreeNodeAdv root, bool value) + { + for (int i = 0; i < root.Nodes.Count; i++) + { + TreeNodeAdv node = root.Nodes[i]; + node.IsExpanded = value; + SetIsExpandedRecursive(node, value); + } + } + + private void CreateRowMap() + { + RowMap.Clear(); + int row = 0; + _contentWidth = 0; + foreach (TreeNodeAdv node in VisibleNodes) + { + node.Row = row; + RowMap.Add(node); + if (!UseColumns) + { + _contentWidth = Math.Max(_contentWidth, GetNodeWidth(node)); + } + row++; + } + if (UseColumns) + { + _contentWidth = 0; + foreach (TreeColumn col in _columns) + if (col.IsVisible) + _contentWidth += col.Width; + } + } + + private int GetNodeWidth(TreeNodeAdv node) + { + if (node.RightBounds == null) + { + Rectangle res = GetNodeBounds(GetNodeControls(node, Rectangle.Empty)); + node.RightBounds = res.Right; + } + return node.RightBounds.Value; + } + + internal Rectangle GetNodeBounds(TreeNodeAdv node) + { + return GetNodeBounds(GetNodeControls(node)); + } + + private Rectangle GetNodeBounds(IEnumerable nodeControls) + { + Rectangle res = Rectangle.Empty; + foreach (NodeControlInfo info in nodeControls) + { + if (res == Rectangle.Empty) + res = info.Bounds; + else + res = Rectangle.Union(res, info.Bounds); + } + return res; + } + + private void _vScrollBar_ValueChanged(object sender, EventArgs e) + { + FirstVisibleRow = _vScrollBar.Value; + } + + private void _hScrollBar_ValueChanged(object sender, EventArgs e) + { + OffsetX = _hScrollBar.Value; + } + + private void _vScrollBar_Scroll(object sender, ScrollEventArgs e) + { + OnScroll(e); + } + + private void _hScrollBar_Scroll(object sender, ScrollEventArgs e) + { + OnScroll(e); + } + + internal void SmartFullUpdate() + { + if (_suspendUpdate) + _needFullUpdate = true; + else + FullUpdate(); + } + + internal bool IsMyNode(TreeNodeAdv node) + { + if (node == null) + return false; + + if (node.Tree != this) + return false; + + while (node.Parent != null) + node = node.Parent; + + return node == _root; + } + + internal void UpdateSelection() + { + bool flag = false; + + if (!IsMyNode(CurrentNode)) + CurrentNode = null; + if (!IsMyNode(_selectionStart)) + _selectionStart = null; + + for (int i = Selection.Count - 1; i >= 0; i--) + if (!IsMyNode(Selection[i])) + { + flag = true; + Selection.RemoveAt(i); + } + + if (flag) + OnSelectionChanged(); + } + + internal void ChangeColumnWidth(TreeColumn column) + { + if (!(_input is ResizeColumnState)) + { + FullUpdate(); + OnColumnWidthChanged(column); + } + } + + public TreeNodeAdv FindNode(TreePath path) + { + return FindNode(path, false); + } + + public TreeNodeAdv FindNode(TreePath path, bool readChilds) + { + if (path.IsEmpty()) + return _root; + else + return FindNode(_root, path, 0, readChilds); + } + + private TreeNodeAdv FindNode(TreeNodeAdv root, TreePath path, int level, bool readChilds) + { + if (!root.IsExpandedOnce && readChilds) + ReadChilds(root); + + for (int i = 0; i < root.Nodes.Count; i++) + { + TreeNodeAdv node = root.Nodes[i]; + if (node.Tag == path.FullPath[level]) + { + if (level == path.FullPath.Length - 1) + return node; + else + return FindNode(node, path, level + 1, readChilds); + } + } + return null; + } + + public TreeNodeAdv FindNodeByTag(object tag) + { + return FindNodeByTag(_root, tag); + } + + private TreeNodeAdv FindNodeByTag(TreeNodeAdv root, object tag) + { + foreach (TreeNodeAdv node in root.Nodes) + { + if (node.Tag == tag) + return node; + TreeNodeAdv res = FindNodeByTag(node, tag); + if (res != null) + return res; + } + return null; + } + + public void SelectAllNodes() + { + SuspendSelectionEvent = true; + try + { + if (SelectionMode == TreeSelectionMode.MultiSameParent) + { + if (CurrentNode != null) + { + foreach (TreeNodeAdv n in CurrentNode.Parent.Nodes) + n.IsSelected = true; + } + } + else if (SelectionMode == TreeSelectionMode.Multi) + { + SelectNodes(Root.Nodes); + } + } + finally + { + SuspendSelectionEvent = false; + } + } + + private void SelectNodes(Collection nodes) + { + foreach (TreeNodeAdv n in nodes) + { + n.IsSelected = true; + if (n.IsExpanded) + SelectNodes(n.Nodes); + } + } + + #region ModelEvents + private void BindModelEvents() + { + _model.NodesChanged += new EventHandler(_model_NodesChanged); + _model.NodesInserted += new EventHandler(_model_NodesInserted); + _model.NodesRemoved += new EventHandler(_model_NodesRemoved); + _model.StructureChanged += new EventHandler(_model_StructureChanged); + } + + private void UnbindModelEvents() + { + _model.NodesChanged -= new EventHandler(_model_NodesChanged); + _model.NodesInserted -= new EventHandler(_model_NodesInserted); + _model.NodesRemoved -= new EventHandler(_model_NodesRemoved); + _model.StructureChanged -= new EventHandler(_model_StructureChanged); + } + + private void _model_StructureChanged(object sender, TreePathEventArgs e) + { + if (e.Path == null) + throw new ArgumentNullException(); + + TreeNodeAdv node = FindNode(e.Path); + if (node != null) + { + if (node != Root) + node.IsLeaf = Model.IsLeaf(GetPath(node)); + + var list = new Dictionary(); + SaveExpandedNodes(node, list); + ReadChilds(node); + RestoreExpandedNodes(node, list); + + UpdateSelection(); + SmartFullUpdate(); + } + //else + // throw new ArgumentException("Path not found"); + } + + private void RestoreExpandedNodes(TreeNodeAdv node, Dictionary list) + { + if (node.Tag != null && list.ContainsKey(node.Tag)) + { + node.IsExpanded = true; + foreach (var child in node.Children) + RestoreExpandedNodes(child, list); + } + } + + private void SaveExpandedNodes(TreeNodeAdv node, Dictionary list) + { + if (node.IsExpanded && node.Tag != null) + { + list.Add(node.Tag, null); + foreach (var child in node.Children) + SaveExpandedNodes(child, list); + } + } + + private void _model_NodesRemoved(object sender, TreeModelEventArgs e) + { + TreeNodeAdv parent = FindNode(e.Path); + if (parent != null) + { + if (e.Indices != null) + { + List list = new List(e.Indices); + list.Sort(); + for (int n = list.Count - 1; n >= 0; n--) + { + int index = list[n]; + if (index >= 0 && index <= parent.Nodes.Count) + parent.Nodes.RemoveAt(index); + else + throw new ArgumentOutOfRangeException("Index out of range"); + } + } + else + { + for (int i = parent.Nodes.Count - 1; i >= 0; i--) + { + for (int n = 0; n < e.Children.Length; n++) + if (parent.Nodes[i].Tag == e.Children[n]) + { + parent.Nodes.RemoveAt(i); + break; + } + } + } + } + UpdateSelection(); + SmartFullUpdate(); + } + + private void _model_NodesInserted(object sender, TreeModelEventArgs e) + { + if (e.Indices == null) + throw new ArgumentNullException("Indices"); + + TreeNodeAdv parent = FindNode(e.Path); + if (parent != null) + { + for (int i = 0; i < e.Children.Length; i++) + AddNewNode(parent, e.Children[i], e.Indices[i]); + } + SmartFullUpdate(); + } + + private void _model_NodesChanged(object sender, TreeModelEventArgs e) + { + TreeNodeAdv parent = FindNode(e.Path); + if (parent != null && parent.IsVisible && parent.IsExpanded) + { + if (InvokeRequired) + BeginInvoke(new UpdateContentWidthDelegate(ClearNodesSize), e, parent); + else + ClearNodesSize(e, parent); + SmartFullUpdate(); + } + } + + private delegate void UpdateContentWidthDelegate(TreeModelEventArgs e, TreeNodeAdv parent); + private void ClearNodesSize(TreeModelEventArgs e, TreeNodeAdv parent) + { + if (e.Indices != null) + { + foreach (int index in e.Indices) + { + if (index >= 0 && index < parent.Nodes.Count) + { + TreeNodeAdv node = parent.Nodes[index]; + node.Height = node.RightBounds = null; + } + else + throw new ArgumentOutOfRangeException("Index out of range"); + } + } + else + { + foreach (TreeNodeAdv node in parent.Nodes) + { + foreach (object obj in e.Children) + if (node.Tag == obj) + { + node.Height = node.RightBounds = null; + } + } + } + } + #endregion + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.resx b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.resx new file mode 100644 index 0000000..f11f8f7 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 127, 17 + + + 17, 17 + + + 236, 17 + + + False + + \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdvCancelEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdvCancelEventArgs.cs new file mode 100644 index 0000000..2fb0827 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdvCancelEventArgs.cs @@ -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) + { + } + + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdvEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdvEventArgs.cs new file mode 100644 index 0000000..c041fc4 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdvEventArgs.cs @@ -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; + } + } +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewRowDrawEventArgs.cs b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewRowDrawEventArgs.cs new file mode 100644 index 0000000..f27f001 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewRowDrawEventArgs.cs @@ -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; } + } + } + +} diff --git a/LibreHardwareMonitor-0.9.4/Aga.Controls/license.txt b/LibreHardwareMonitor-0.9.4/Aga.Controls/license.txt new file mode 100644 index 0000000..428ceed --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Aga.Controls/license.txt @@ -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. \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/Directory.Build.props b/LibreHardwareMonitor-0.9.4/Directory.Build.props new file mode 100644 index 0000000..8257db3 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/Directory.Build.props @@ -0,0 +1,6 @@ + + + 0.9.4 + LibreHardwareMonitor + + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InpOut32.Net/CSharpExample.cs b/LibreHardwareMonitor-0.9.4/InpOut/InpOut32.Net/CSharpExample.cs new file mode 100644 index 0000000..28b4ff2 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InpOut32.Net/CSharpExample.cs @@ -0,0 +1,274 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +using System.Runtime.InteropServices; + +namespace InpOut32.Net +{ + public partial class CSharpExample : Form + { + + [DllImport("inpout32.dll")] + private static extern UInt32 IsInpOutDriverOpen(); + [DllImport("inpout32.dll")] + private static extern void Out32(short PortAddress, short Data); + [DllImport("inpout32.dll")] + private static extern char Inp32(short PortAddress); + + [DllImport("inpout32.dll")] + private static extern void DlPortWritePortUshort(short PortAddress, ushort Data); + [DllImport("inpout32.dll")] + private static extern ushort DlPortReadPortUshort(short PortAddress); + + [DllImport("inpout32.dll")] + private static extern void DlPortWritePortUlong(int PortAddress, uint Data); + [DllImport("inpout32.dll")] + private static extern uint DlPortReadPortUlong(int PortAddress); + + [DllImport("inpoutx64.dll")] + private static extern bool GetPhysLong(ref int PortAddress, ref uint Data); + [DllImport("inpoutx64.dll")] + private static extern bool SetPhysLong(ref int PortAddress, ref uint Data); + + + [DllImport("inpoutx64.dll", EntryPoint="IsInpOutDriverOpen")] + private static extern UInt32 IsInpOutDriverOpen_x64(); + [DllImport("inpoutx64.dll", EntryPoint = "Out32")] + private static extern void Out32_x64(short PortAddress, short Data); + [DllImport("inpoutx64.dll", EntryPoint = "Inp32")] + private static extern char Inp32_x64(short PortAddress); + + [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUshort")] + private static extern void DlPortWritePortUshort_x64(short PortAddress, ushort Data); + [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUshort")] + private static extern ushort DlPortReadPortUshort_x64(short PortAddress); + + [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUlong")] + private static extern void DlPortWritePortUlong_x64(int PortAddress, uint Data); + [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUlong")] + private static extern uint DlPortReadPortUlong_x64(int PortAddress); + + [DllImport("inpoutx64.dll", EntryPoint = "GetPhysLong")] + private static extern bool GetPhysLong_x64(ref int PortAddress, ref uint Data); + [DllImport("inpoutx64.dll", EntryPoint = "SetPhysLong")] + private static extern bool SetPhysLong_x64(ref int PortAddress, ref uint Data); + + + bool m_bX64 = false; + + public CSharpExample() + { + InitializeComponent(); + try + { + uint nResult = 0; + try + { + nResult = IsInpOutDriverOpen(); + } + catch (BadImageFormatException) + { + nResult = IsInpOutDriverOpen_x64(); + if (nResult != 0) + m_bX64 = true; + + } + + if (nResult == 0) + { + lblMessage.Text = "Unable to open InpOut32 driver"; + button1.Enabled = false; + button2.Enabled = false; + button3.Enabled = false; + button4.Enabled = false; + button5.Enabled = false; + button6.Enabled = false; + button7.Enabled = false; + } + } + catch (DllNotFoundException ex) + { + System.Diagnostics.Debug.WriteLine(ex.ToString()); + lblMessage.Text = "Unable to find InpOut32.dll"; + button1.Enabled = false; + button2.Enabled = false; + button3.Enabled = false; + button4.Enabled = false; + button5.Enabled = false; + button6.Enabled = false; + button7.Enabled = false; + } + } + + private void button1_Click(object sender, EventArgs e) + { + try + { + short iPort = Convert.ToInt16(textBox1.Text); + + char c; + if (m_bX64) + c = Inp32_x64(iPort); + else + c = Inp32(iPort); + + textBox2.Text = Convert.ToInt32(c).ToString(); + } + catch (Exception ex) + { + MessageBox.Show("An error occured:\n" + ex.Message); + } + } + + private void button2_Click(object sender, EventArgs e) + { + try + { + short iPort = Convert.ToInt16(textBox1.Text); + short iData = Convert.ToInt16(textBox2.Text); + textBox2.Text = ""; + if (m_bX64) + Out32_x64(iPort, iData); + else + Out32(iPort, iData); + + + } + catch (Exception ex) + { + MessageBox.Show("An error occured:\n" + ex.Message); + } + } + + private void button3_Click(object sender, EventArgs e) + { + try + { + short iPort = Convert.ToInt16(textBox1.Text); + ushort s; + if (m_bX64) + s = DlPortReadPortUshort_x64(iPort); + else + s = DlPortReadPortUshort(iPort); + + textBox2.Text = Convert.ToUInt16(s).ToString(); + } + catch (Exception ex) + { + MessageBox.Show("An error occured:\n" + ex.Message); + } + } + + private void button4_Click(object sender, EventArgs e) + { + try + { + int nPort = Convert.ToInt32(textBox1.Text); + + uint l; + if (m_bX64) + l = DlPortReadPortUlong_x64(nPort); + else + l = DlPortReadPortUlong(nPort); + + textBox2.Text = l.ToString(); + } + catch (Exception ex) + { + MessageBox.Show("An error occured:\n" + ex.Message); + } + } + + private void button5_Click(object sender, EventArgs e) + { + try + { + short sPort = Convert.ToInt16(textBox1.Text); + ushort iData = Convert.ToUInt16(textBox2.Text); + textBox2.Text = ""; + + if (m_bX64) + DlPortWritePortUshort_x64(sPort, iData); + else + DlPortWritePortUshort(sPort, iData); + } + catch (Exception ex) + { + MessageBox.Show("An error occured:\n" + ex.Message); + } + } + + private void button6_Click(object sender, EventArgs e) + { + try + { + int nPort = Convert.ToInt32(textBox1.Text); + uint nData = Convert.ToUInt32(textBox2.Text); + textBox2.Text = ""; + if (m_bX64) + DlPortWritePortUlong_x64(nPort, nData); + else + DlPortWritePortUlong(nPort, nData); + } + catch (Exception ex) + { + MessageBox.Show("An error occured:\n" + ex.Message); + } + } + + private void Beep(uint freq) + { + if (m_bX64) + { + Out32_x64(0x43, 0xB6); + Out32_x64(0x42, (byte)(freq & 0xFF)); + Out32_x64(0x42, (byte)(freq >> 9)); + System.Threading.Thread.Sleep(10); + Out32_x64(0x61, (byte)(Convert.ToByte(Inp32_x64(0x61)) | 0x03)); + } + else + { + Out32(0x43, 0xB6); + Out32(0x42, (byte)(freq & 0xFF)); + Out32(0x42, (byte)(freq >> 9)); + System.Threading.Thread.Sleep(10); + Out32(0x61, (byte)(Convert.ToByte(Inp32(0x61)) | 0x03)); + } + } + + private void StopBeep() + { + if (m_bX64) + Out32_x64(0x61, (byte)(Convert.ToByte(Inp32_x64(0x61)) & 0xFC)); + else + Out32(0x61, (byte)(Convert.ToByte(Inp32(0x61)) & 0xFC)); + } + + private void CSharpExample_Load(object sender, EventArgs e) + { + button7_Click(this, null); + } + + + private void ThreadBeeper() + { + for (uint i = 440000; i < 500000; i += 1000) + { + uint freq = 1193180000 / i; // 440Hz + Beep(freq); + } + StopBeep(); + } + + private void button7_Click(object sender, EventArgs e) + { + System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadBeeper)); + t.Start(); + } + } +} \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.cpp b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.cpp new file mode 100644 index 0000000..142571c --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.cpp @@ -0,0 +1,35 @@ +// InstallDriver.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "InstallDriver.h" +#include "..\inpout32.h" +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +// The one and only application object +int APIENTRY _tWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + int nRetCode = 0; + BOOL bResult = IsInpOutDriverOpen(); + + if (IsXP64Bit()) + { + if (bResult) + MessageBox(NULL, _T("Successfully installed and opened\n64bit InpOut driver InpOutx64.sys."), _T("InpOut Installation"), 0); + else + MessageBox(NULL, _T("Unable to install or open the\n64bit InpOut driver InpOutx64.sys.\n\nPlease try running as Administrator"), _T("InpOut Installation"), 0); + } + else + { + if (bResult) + MessageBox(NULL, _T("Successfully installed and opened\n32bit InpOut driver InpOut32.sys."), _T("InpOut Installation"), 0); + else + MessageBox(NULL, _T("Unable to install or open the\n32bit InpOut driver InpOut32.sys.\n\nPlease try running as Administrator"), _T("InpOut Installation"), 0); + } + return nRetCode; +} diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.h b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.h new file mode 100644 index 0000000..d00d47e --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.manifest b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.manifest new file mode 100644 index 0000000..c4b6440 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.manifest @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.rc b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.rc new file mode 100644 index 0000000..21ebcee --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.rc @@ -0,0 +1,113 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,4,0,0 + PRODUCTVERSION 1,4,0,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "CompanyName", "Highresolution Enterprises" + VALUE "FileDescription", "InstallDriver Windows Vista/7 support application" + VALUE "FileVersion", "1, 4, 0, 0" + VALUE "InternalName", "InstallDriver" + VALUE "LegalCopyright", "Copyright (C) 2007-2011 Highresolution Enterprises" + VALUE "OriginalFilename", "InstallDriver.exe" + VALUE "ProductName", "InstallDriver Application" + VALUE "ProductVersion", "1, 4, 0, 0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "InstallDriver" +END + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.vcproj b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.vcproj new file mode 100644 index 0000000..4990c69 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/InstallDriver.vcproj @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/ReadMe.txt b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/ReadMe.txt new file mode 100644 index 0000000..d6dc61e --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/ReadMe.txt @@ -0,0 +1,46 @@ +======================================================================== + CONSOLE APPLICATION : InstallDriver Project Overview +======================================================================== + +AppWizard has created this InstallDriver application for you. + +This file contains a summary of what you will find in each of the files that +make up your InstallDriver application. + + +InstallDriver.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +InstallDriver.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +AppWizard has created the following resources: + +InstallDriver.rc + This is a listing of all of the Microsoft Windows resources that the + program uses. It includes the icons, bitmaps, and cursors that are stored + in the RES subdirectory. This file can be directly edited in Microsoft + Visual C++. + +Resource.h + This is the standard header file, which defines new resource IDs. + Microsoft Visual C++ reads and updates this file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named InstallDriver.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/Resource.h b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/Resource.h new file mode 100644 index 0000000..0d098f8 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/Resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by InstallDriver.rc +// +#define IDR_MANIFEST 1 +#define IDS_APP_TITLE 103 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/stdafx.cpp b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/stdafx.cpp new file mode 100644 index 0000000..ceedb5d --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// InstallDriver.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/stdafx.h b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/stdafx.h new file mode 100644 index 0000000..42732dc --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/InstallDriver/stdafx.h @@ -0,0 +1,27 @@ +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + +// C RunTime Header Files +#include +#include +#include +#include \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/InpOut/ReadMe.txt b/LibreHardwareMonitor-0.9.4/InpOut/ReadMe.txt new file mode 100644 index 0000000..c6e0f8d --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/ReadMe.txt @@ -0,0 +1,24 @@ +InpOut32Drv Driver Interface DLL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Modified for x64 compatibility and built by Phillip Gibbons (Phil@highrez.co.uk). +See http://www.highrez.co.uk/Downloads/InpOut32 or the Highrez Forums (http://forums.highrez.co.uk) for information. +Many thanks to Red Fox UK for supporting the community and providing Driver signatures allowing Vista/7 x64 compatibility. + + + +Based on the original written by Logix4U (www.logix4u.net). + + +Notes: + + The InpOut32 device driver supports writing to "old fashioned" hardware port addresses. + It does NOT support USB devices such as USB Parallel ports or even PCI parallel ports (as I am lead to believe). + + + The device driver is installed at runtime. To do this however needs administrator privileges. + On Vista & later, using UAC, you can run the InstallDriver.exe in the \Win32 folder to install the driver + appropriate for your OS. Doing so will request elevation and ask for your permission (or for the administrator + password). Once the driver is installed for the first time, it can then be used by any user *without* + administrator privileges + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/StdAfx.cpp b/LibreHardwareMonitor-0.9.4/InpOut/StdAfx.cpp new file mode 100644 index 0000000..6b6294f --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// inpout32drv.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/LibreHardwareMonitor-0.9.4/InpOut/StdAfx.h b/LibreHardwareMonitor-0.9.4/InpOut/StdAfx.h new file mode 100644 index 0000000..92e3273 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/StdAfx.h @@ -0,0 +1,39 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__7ACF5BF3_42A3_43EB_9034_6218487B5231__INCLUDED_) +#define AFX_STDAFX_H__7ACF5BF3_42A3_43EB_9034_6218487B5231__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +#ifndef WINVER +#define WINVER 0x0400 +#endif + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif + +#ifndef _WIN32_WINDOWS +#define _WIN32_WINDOWS 0x0410 +#endif + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif + +#define WIN32_LEAN_AND_MEAN +#include +#include + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__7ACF5BF3_42A3_43EB_9034_6218487B5231__INCLUDED_) diff --git a/LibreHardwareMonitor-0.9.4/InpOut/hwinterfacedrv.h b/LibreHardwareMonitor-0.9.4/InpOut/hwinterfacedrv.h new file mode 100644 index 0000000..9fd4043 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/hwinterfacedrv.h @@ -0,0 +1,29 @@ + +#define IOCTL_READ_PORT_UCHAR -1673519100 //CTL_CODE(40000, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WRITE_PORT_UCHAR -1673519096 //CTL_CODE(40000, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_READ_PORT_USHORT -1673519092 //CTL_CODE(40000, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WRITE_PORT_USHORT -1673519088 //CTL_CODE(40000, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_READ_PORT_ULONG -1673519084 //CTL_CODE(40000, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WRITE_PORT_ULONG -1673519080 //CTL_CODE(40000, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINIO_MAPPHYSTOLIN -1673519076 +#define IOCTL_WINIO_UNMAPPHYSADDR -1673519072 + +BOOL _stdcall IsXP64Bit(); +int SystemVersion(); +BOOL DisableWOW64(PVOID* oldValue); +BOOL RevertWOW64(PVOID* oldValue); + +#pragma pack(push) +#pragma pack(1) + +struct tagPhys32Struct +{ + HANDLE PhysicalMemoryHandle; + SIZE_T dwPhysMemSizeInBytes; + PVOID pvPhysAddress; + PVOID pvPhysMemLin; +}; + +extern struct tagPhys32Struct Phys32Struct; + +#pragma pack(pop) \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpout32.h b/LibreHardwareMonitor-0.9.4/InpOut/inpout32.h new file mode 100644 index 0000000..65df096 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/inpout32.h @@ -0,0 +1,32 @@ +#pragma once + +//Functions exported from DLL. +//For easy inclusion is user projects. +//Original InpOut32 function support +void _stdcall Out32(short PortAddress, short data); +short _stdcall Inp32(short PortAddress); + +//My extra functions for making life easy +BOOL _stdcall IsInpOutDriverOpen(); //Returns TRUE if the InpOut driver was opened successfully +BOOL _stdcall IsXP64Bit(); //Returns TRUE if the OS is 64bit (x64) Windows. + +//DLLPortIO function support +UCHAR _stdcall DlPortReadPortUchar (USHORT port); +void _stdcall DlPortWritePortUchar(USHORT port, UCHAR Value); + +USHORT _stdcall DlPortReadPortUshort (USHORT port); +void _stdcall DlPortWritePortUshort(USHORT port, USHORT Value); + +ULONG _stdcall DlPortReadPortUlong(ULONG port); +void _stdcall DlPortWritePortUlong(ULONG port, ULONG Value); + +//WinIO function support (Untested and probably does NOT work - esp. on x64!) +PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle); +BOOL _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr); +BOOL _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal); +BOOL _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal); + + + + + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpout32.sys b/LibreHardwareMonitor-0.9.4/InpOut/inpout32.sys new file mode 100644 index 0000000..0f68c5e Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/InpOut/inpout32.sys differ diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.cpp b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.cpp new file mode 100644 index 0000000..bdbc248 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.cpp @@ -0,0 +1,691 @@ +/***********************************************************************\ +* * +* InpOut32drv.cpp * +* * +* The entry point for the InpOut DLL * +* Provides the 32 and 64bit implementation of InpOut32 DLL to install * +* and call the appropriate driver and write directly to hardware ports. * +* * +* Written by Phillip Gibbons (Highrez.co.uk) * +* Based on orriginal, written by Logix4U (www.logix4u.net) * +* * +\***********************************************************************/ + +#include "stdafx.h" +#include +#include +#include + +#include "hwinterfacedrv.h" +#include "resource.h" + +int inst32(); +int inst64(); +int start(LPCTSTR pszDriver); + +//First, lets set the DRIVERNAME depending on our configuraiton. +#define DRIVERNAMEx64 _T("inpoutx64\0") +#define DRIVERNAMEi386 _T("inpout32\0") + +char str[10]; +int vv; + +HANDLE hdriver=NULL; +TCHAR path[MAX_PATH]; +HINSTANCE hmodule; +SECURITY_ATTRIBUTES sa; +int sysver; + +int Opendriver(BOOL bX64); +void Closedriver(void); + +BOOL APIENTRY DllMain( HINSTANCE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + hmodule = hModule; + BOOL bx64 = IsXP64Bit(); + switch(ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + sysver = SystemVersion(); + if(sysver==2) + { + Opendriver(bx64); + } + } + + break; + case DLL_PROCESS_DETACH: + { + if(sysver==2) + { + Closedriver(); + } + } + break; + } + return TRUE; +} + +/***********************************************************************/ + +void Closedriver(void) +{ + if (hdriver) + { + OutputDebugString(_T("Closing InpOut driver...\n")); + CloseHandle(hdriver); + hdriver=NULL; + } +} + +void _stdcall Out32(short PortAddress, short data) +{ + { + switch(sysver) + { + case 1: +#ifdef _M_IX86 + _outp( PortAddress,data); //Will ONLY compile on i386 architecture +#endif + break; + case 2: + unsigned int error; + DWORD BytesReturned; + BYTE Buffer[3]={NULL}; + unsigned short* pBuffer; + pBuffer = (unsigned short *)&Buffer[0]; + *pBuffer = LOWORD(PortAddress); + Buffer[2] = LOBYTE(data); + + error = DeviceIoControl(hdriver, + IOCTL_WRITE_PORT_UCHAR, + &Buffer, + 3, + NULL, + 0, + &BytesReturned, + NULL); + break; + } + } +} + +/*********************************************************************/ + +short _stdcall Inp32(short PortAddress) +{ + { + BYTE retval(0); + switch(sysver) + { + case 1: +#ifdef _M_IX86 + retval = _inp(PortAddress); +#endif + return retval; + break; + case 2: + unsigned int error; + DWORD BytesReturned; + unsigned char Buffer[3]={NULL}; + unsigned short * pBuffer; + pBuffer = (unsigned short *)&Buffer; + *pBuffer = LOWORD(PortAddress); + Buffer[2] = 0; + error = DeviceIoControl(hdriver, + IOCTL_READ_PORT_UCHAR, + &Buffer, + 2, + &Buffer, + 1, + &BytesReturned, + NULL); + + if (error==0) + { + DWORD dwError = GetLastError(); + TCHAR tszError[255]; + _stprintf_s(tszError, 255, _T("Error %d\n"), dwError); + OutputDebugString(tszError); + } + + //Do this to ensure only the first byte is returned, we dont really want to return a short as were only reading a byte. + //but we also dont want to change the InpOut interface! + UCHAR ucRes = (UCHAR)Buffer[0]; + return ucRes; + + break; + } + } + return 0; +} + +/*********************************************************************/ + +int Opendriver(BOOL bX64) +{ + OutputDebugString(_T("Attempting to open InpOut driver...\n")); + TCHAR szFileName[MAX_PATH] = {NULL}; + _stprintf_s(szFileName, MAX_PATH, _T("\\\\.\\%s"), bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); + + hdriver = CreateFile(szFileName, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if(hdriver == INVALID_HANDLE_VALUE) + { + if(start(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386)) + { + if (bX64) + inst64(); //Install the x64 driver + else + inst32(); //Install the i386 driver + + int nResult = start(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); + + if (nResult == ERROR_SUCCESS) + { + hdriver = CreateFile(szFileName, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if(hdriver != INVALID_HANDLE_VALUE) + { + OutputDebugString(_T("Successfully opened ")); + OutputDebugString(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); + OutputDebugString(_T(" driver\n")); + return 0; + } + } + else + { + TCHAR szMsg[MAX_PATH] = {NULL}; + _stprintf_s(szMsg, MAX_PATH, _T("Unable to open %s driver. Error code %d.\n"), bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386, nResult); + OutputDebugString(szMsg); + + //RemoveDriver(); + } + } + return 1; + } + OutputDebugString(_T("Successfully opened ")); + OutputDebugString(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); + OutputDebugString(_T(" driver\n")); + return 0; +} + +/***********************************************************************/ +int inst32() +{ + TCHAR szDriverSys[MAX_PATH]; + _tcscpy_s(szDriverSys, MAX_PATH, DRIVERNAMEi386); + _tcscat_s(szDriverSys, MAX_PATH, _T(".sys\0")); + + SC_HANDLE Mgr; + SC_HANDLE Ser; + GetSystemDirectory(path, MAX_PATH); + HRSRC hResource = FindResource(hmodule, MAKEINTRESOURCE(IDR_INPOUT32), _T("bin")); + if(hResource) + { + HGLOBAL binGlob = LoadResource(hmodule, hResource); + + if(binGlob) + { + void *binData = LockResource(binGlob); + + if(binData) + { + HANDLE file; + + _tcscat_s(path, sizeof(path), _T("\\Drivers\\")); + _tcscat_s(path, sizeof(path), szDriverSys); + + file = CreateFile(path, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + 0, + NULL); + + if (file && file != INVALID_HANDLE_VALUE) + { + DWORD size, written; + size = SizeofResource(hmodule, hResource); + WriteFile(file, binData, size, &written, NULL); + CloseHandle(file); + } + else + { + //Error + } + } + } + } + + Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS); + if (Mgr == NULL) + { //No permission to create service + if (GetLastError() == ERROR_ACCESS_DENIED) + { + return 5; // error access denied + } + } + else + { + TCHAR szFullPath[MAX_PATH] = _T("System32\\Drivers\\\0"); + _tcscat_s(szFullPath, MAX_PATH, szDriverSys); + Ser = CreateService (Mgr, + DRIVERNAMEi386, + DRIVERNAMEi386, + SERVICE_ALL_ACCESS, + SERVICE_KERNEL_DRIVER, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + szFullPath, + NULL, + NULL, + NULL, + NULL, + NULL + ); + } + CloseServiceHandle(Ser); + CloseServiceHandle(Mgr); + + return 0; +} + +int inst64() +{ + TCHAR szDriverSys[MAX_PATH]; + _tcscpy_s(szDriverSys, MAX_PATH, DRIVERNAMEx64); + _tcscat_s(szDriverSys, MAX_PATH, _T(".sys\0")); + + SC_HANDLE Mgr; + SC_HANDLE Ser; + GetSystemDirectory(path, MAX_PATH); + HRSRC hResource = FindResource(hmodule, MAKEINTRESOURCE(IDR_INPOUTX64), _T("bin")); + if(hResource) + { + HGLOBAL binGlob = LoadResource(hmodule, hResource); + + if(binGlob) + { + void *binData = LockResource(binGlob); + + if(binData) + { + HANDLE file; + _tcscat_s(path, sizeof(path), _T("\\Drivers\\")); + _tcscat_s(path, sizeof(path), szDriverSys); + + PVOID OldValue; + DisableWOW64(&OldValue); + file = CreateFile(path, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + 0, + NULL); + + if(file && file != INVALID_HANDLE_VALUE) + { + DWORD size, written; + + size = SizeofResource(hmodule, hResource); + WriteFile(file, binData, size, &written, NULL); + CloseHandle(file); + } + else + { + //error + } + RevertWOW64(&OldValue); + } + } + } + + Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS); + if (Mgr == NULL) + { //No permission to create service + if (GetLastError() == ERROR_ACCESS_DENIED) + { + return 5; // error access denied + } + } + else + { + TCHAR szFullPath[MAX_PATH] = _T("System32\\Drivers\\\0"); + _tcscat_s(szFullPath, MAX_PATH, szDriverSys); + Ser = CreateService (Mgr, + DRIVERNAMEx64, + DRIVERNAMEx64, + SERVICE_ALL_ACCESS, + SERVICE_KERNEL_DRIVER, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + szFullPath, + NULL, + NULL, + NULL, + NULL, + NULL + ); + } + CloseServiceHandle(Ser); + CloseServiceHandle(Mgr); + + return 0; +} + +/**************************************************************************/ +int start(LPCTSTR pszDriver) +{ + SC_HANDLE Mgr; + SC_HANDLE Ser; + + Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS); + + if (Mgr == NULL) + { //No permission to create service + if (GetLastError() == ERROR_ACCESS_DENIED) + { + Mgr = OpenSCManager (NULL, NULL, GENERIC_READ); + Ser = OpenService(Mgr, pszDriver, GENERIC_EXECUTE); + if (Ser) + { // we have permission to start the service + if(!StartService(Ser,0,NULL)) + { + CloseServiceHandle (Ser); + return 4; // we could open the service but unable to start + } + } + } + } + else + {// Successfuly opened Service Manager with full access + Ser = OpenService(Mgr, pszDriver, SERVICE_ALL_ACCESS); + if (Ser) + { + if(!StartService(Ser,0,NULL)) + { + CloseServiceHandle (Ser); + return 3; // opened the Service handle with full access permission, but unable to start + } + else + { + CloseServiceHandle (Ser); + return 0; + } + } + } + return 1; +} + +BOOL _stdcall IsInpOutDriverOpen() +{ + sysver = SystemVersion(); + if (sysver==2) + { + if (hdriver!=INVALID_HANDLE_VALUE && hdriver != NULL) + return TRUE; + } + else if (sysver==1) + { + return TRUE; + } + return FALSE; +} + +UCHAR _stdcall DlPortReadPortUchar (USHORT port) +{ + UCHAR retval(0); + switch(sysver) + { + case 1: +#ifdef _M_IX86 + retval = _inp((USHORT)port); +#endif + return retval; + break; + case 2: + unsigned int error; + DWORD BytesReturned; + BYTE Buffer[3]={NULL}; + unsigned short * pBuffer; + pBuffer = (unsigned short *)&Buffer; + *pBuffer = port; + Buffer[2] = 0; + error = DeviceIoControl(hdriver, + IOCTL_READ_PORT_UCHAR, + &Buffer, + sizeof(Buffer), + &Buffer, + sizeof(Buffer), + &BytesReturned, + NULL); + + return((UCHAR)Buffer[0]); + + break; + } + return 0; +} + +void _stdcall DlPortWritePortUchar (USHORT port, UCHAR Value) +{ + switch(sysver) + { + case 1: +#ifdef _M_IX86 + _outp((UINT)port,Value); //Will ONLY compile on i386 architecture +#endif + break; + case 2: + unsigned int error; + DWORD BytesReturned; + BYTE Buffer[3]={NULL}; + unsigned short * pBuffer; + pBuffer = (unsigned short *)&Buffer[0]; + *pBuffer = port; + Buffer[2] = Value; + + error = DeviceIoControl(hdriver, + IOCTL_WRITE_PORT_UCHAR, + &Buffer, + sizeof(Buffer), + NULL, + 0, + &BytesReturned, + NULL); + break; + } +} + +USHORT _stdcall DlPortReadPortUshort (USHORT port) +{ + if (sysver!=2) + return 0; + + ULONG retval(0); + unsigned int error; + DWORD BytesReturned; + unsigned short sPort=port; + error = DeviceIoControl(hdriver, + IOCTL_READ_PORT_USHORT, + &sPort, + sizeof(unsigned short), + &sPort, + sizeof(unsigned short), + &BytesReturned, + NULL); + return(sPort); +} + +void _stdcall DlPortWritePortUshort (USHORT port, USHORT Value) +{ + if (sysver!=2) + return; + + unsigned int error; + DWORD BytesReturned; + BYTE Buffer[5]={NULL}; + unsigned short * pBuffer; + pBuffer = (unsigned short *)&Buffer[0]; + *pBuffer = LOWORD(port); + *(pBuffer+1) = Value; + + error = DeviceIoControl(hdriver, + IOCTL_WRITE_PORT_USHORT, + &Buffer, + sizeof(Buffer), + NULL, + 0, + &BytesReturned, + NULL); +} + +ULONG _stdcall DlPortReadPortUlong(ULONG port) +{ + if (sysver!=2) + return 0; + + ULONG retval(0); + unsigned int error; + DWORD BytesReturned; + unsigned long lPort=port; + + PULONG ulBuffer; + ulBuffer = (PULONG)&lPort; + ULONG test = ulBuffer[0]; + + error = DeviceIoControl(hdriver, + IOCTL_READ_PORT_ULONG, + &lPort, + sizeof(unsigned long), + &lPort, + sizeof(unsigned long), + &BytesReturned, + NULL); + return(lPort); +} + +void _stdcall DlPortWritePortUlong (ULONG port, ULONG Value) +{ + if (sysver!=2) + return; + + unsigned int error; + DWORD BytesReturned; + BYTE Buffer[8] = {NULL}; + unsigned long* pBuffer; + pBuffer = (unsigned long*)&Buffer[0]; + *pBuffer = port; + *(pBuffer+1) = Value; + + error = DeviceIoControl(hdriver, + IOCTL_WRITE_PORT_ULONG, + &Buffer, + sizeof(Buffer), + NULL, + 0, + &BytesReturned, + NULL); +} + + +// Support functions for WinIO +PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle) +{ + PBYTE pbLinAddr; + tagPhys32Struct Phys32Struct; + DWORD dwBytesReturned; + + if (sysver!=2) + return false; + + Phys32Struct.dwPhysMemSizeInBytes = dwPhysSize; + Phys32Struct.pvPhysAddress = pbPhysAddr; + + if (!DeviceIoControl(hdriver, IOCTL_WINIO_MAPPHYSTOLIN, &Phys32Struct, + sizeof(tagPhys32Struct), &Phys32Struct, sizeof(tagPhys32Struct), + &dwBytesReturned, NULL)) + return NULL; + else + { +#ifdef _M_X64 + pbLinAddr = (PBYTE)((LONGLONG)Phys32Struct.pvPhysMemLin + (LONGLONG)pbPhysAddr - (LONGLONG)Phys32Struct.pvPhysAddress); +#else + pbLinAddr = (PBYTE)((DWORD)Phys32Struct.pvPhysMemLin + (DWORD)pbPhysAddr - (DWORD)Phys32Struct.pvPhysAddress); +#endif + *pPhysicalMemoryHandle = Phys32Struct.PhysicalMemoryHandle; + } + return pbLinAddr; +} + + +BOOL _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr) +{ + tagPhys32Struct Phys32Struct; + DWORD dwBytesReturned; + + if (sysver!=2) + return false; + + Phys32Struct.PhysicalMemoryHandle = PhysicalMemoryHandle; + Phys32Struct.pvPhysMemLin = pbLinAddr; + + if (!DeviceIoControl(hdriver, IOCTL_WINIO_UNMAPPHYSADDR, &Phys32Struct, + sizeof(tagPhys32Struct), NULL, 0, &dwBytesReturned, NULL)) + return false; + + return true; +} + +BOOL _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal) +{ + PDWORD pdwLinAddr; + HANDLE PhysicalMemoryHandle; + + if (sysver!=2) + return false; + + pdwLinAddr = (PDWORD)MapPhysToLin(pbPhysAddr, 4, &PhysicalMemoryHandle); + if (pdwLinAddr == NULL) + return false; + + *pdwPhysVal = *pdwLinAddr; + UnmapPhysicalMemory(PhysicalMemoryHandle, (PBYTE)pdwLinAddr); + return true; +} + + +BOOL _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal) +{ + PDWORD pdwLinAddr; + HANDLE PhysicalMemoryHandle; + if (sysver!=2) + return false; + + pdwLinAddr = (PDWORD)MapPhysToLin(pbPhysAddr, 4, &PhysicalMemoryHandle); + if (pdwLinAddr == NULL) + return false; + + *pdwLinAddr = dwPhysVal; + UnmapPhysicalMemory(PhysicalMemoryHandle, (PBYTE)pdwLinAddr); + return true; +} diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.def b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.def new file mode 100644 index 0000000..e2b60cf --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.def @@ -0,0 +1,18 @@ +EXPORTS + +Inp32 @1 +Out32 @2 +IsInpOutDriverOpen @3 + +DlPortReadPortUchar @4 +DlPortWritePortUchar @5 +DlPortReadPortUshort @6 +DlPortWritePortUshort @7 +DlPortReadPortUlong @8 +DlPortWritePortUlong @9 +IsXP64Bit @10 + +MapPhysToLin @11 +UnmapPhysicalMemory @12 +GetPhysLong @13 +SetPhysLong @14 \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.rc b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.rc new file mode 100644 index 0000000..700ac33 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.rc @@ -0,0 +1,125 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,5,0,0 + PRODUCTVERSION 1,5,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080004b0" + BEGIN + VALUE "Comments", "Includes signed x64 drivers for Vista compatibility." + VALUE "CompanyName", "Highresolution Enterprises" + VALUE "FileDescription", "inpout32/64" + VALUE "FileVersion", "1, 5, 0, 0" + VALUE "InternalName", "inpout32" + VALUE "LegalCopyright", "Freeware" + VALUE "LegalTrademarks", "Copyright 2008-2011 Highresolution Enterprises. Portions Copyright Logix4U" + VALUE "OriginalFilename", "inpout32.dll" + VALUE "ProductName", "inpout32" + VALUE "ProductVersion", "1, 5, 0, 0" + VALUE "SpecialBuild", "x64 Compatible build\r\nIncludes basic DLPortIO Compatibility\r\nIncludes signed drivers (Thanks to Red Fox UK) for Vista x64 compatiblity.\r\n" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x800, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Neutral (Sys. Default) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// BIN +// + +IDR_INPOUT32 BIN "inpout32.sys" +IDR_INPOUTX64 BIN "inpoutx64.sys" +#endif // Neutral (Sys. Default) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.sln b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.sln new file mode 100644 index 0000000..9d797be --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.sln @@ -0,0 +1,100 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inpout32drv", "inpout32drv.vcproj", "{18AEFF0B-D208-45B0-88E1-7057B9BA78F3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InstallDriver", "InstallDriver\InstallDriver.vcproj", "{233B1347-4B15-42DC-AC23-C2FE2ABEAF54}" + ProjectSection(ProjectDependencies) = postProject + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3} = {18AEFF0B-D208-45B0-88E1-7057B9BA78F3} + EndProjectSection +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InpOut32.VB.Net", "InpOut32.Net\InpOut32.VB.Net\InpOut32.VB.Net.vbproj", "{F90F25E7-E912-4948-B9CE-168FFA3014C8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InpOut32.CSharp.Net", "InpOut32.Net\InpOut32.CSharp.Net\InpOut32.CSharp.Net.csproj", "{784B3C36-7CAD-4B06-82A5-E60D17193F27}" +EndProject +Global + GlobalSection(SourceCodeControl) = preSolution + SccNumberOfProjects = 5 + SccLocalPath0 = . + SccProjectUniqueName1 = inpout32drv.vcproj + SccLocalPath1 = . + SccProjectUniqueName2 = InstallDriver\\InstallDriver.vcproj + SccLocalPath2 = . + SccProjectFilePathRelativizedFromConnection2 = InstallDriver\\ + SccProjectUniqueName3 = InpOut32.Net\\InpOut32.VB.Net\\InpOut32.VB.Net.vbproj + SccLocalPath3 = . + SccProjectFilePathRelativizedFromConnection3 = InpOut32.Net\\InpOut32.VB.Net\\ + SccProjectUniqueName4 = InpOut32.Net\\InpOut32.CSharp.Net\\InpOut32.CSharp.Net.csproj + SccProjectName4 = \u0022$/inpout32drv.root/inpout32drv/InpOut32.Net/InpOut32.CSharp.Net\u0022,\u0020DHHAAAAA + SccLocalPath4 = InpOut32.Net\\InpOut32.CSharp.Net + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Any CPU.ActiveCfg = Debug|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Mixed Platforms.Build.0 = Debug|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Win32.ActiveCfg = Debug|Win32 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Win32.Build.0 = Debug|Win32 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|x64.ActiveCfg = Debug|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|x64.Build.0 = Debug|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Any CPU.ActiveCfg = Release|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Mixed Platforms.Build.0 = Release|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Win32.ActiveCfg = Release|Win32 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Win32.Build.0 = Release|Win32 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|x64.ActiveCfg = Release|x64 + {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|x64.Build.0 = Release|x64 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Win32.ActiveCfg = Debug|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Win32.Build.0 = Debug|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|x64.ActiveCfg = Debug|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Any CPU.ActiveCfg = Release|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Mixed Platforms.Build.0 = Release|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Win32.ActiveCfg = Release|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Win32.Build.0 = Release|Win32 + {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|x64.ActiveCfg = Release|Win32 + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Win32.Build.0 = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|x64.ActiveCfg = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|x64.Build.0 = Debug|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Any CPU.Build.0 = Release|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Win32.ActiveCfg = Release|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Win32.Build.0 = Release|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|x64.ActiveCfg = Release|Any CPU + {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|x64.Build.0 = Release|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Win32.ActiveCfg = Debug|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|x64.ActiveCfg = Debug|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Any CPU.Build.0 = Release|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Win32.ActiveCfg = Release|Any CPU + {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|x64.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.vcproj b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.vcproj new file mode 100644 index 0000000..be97fea --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.vcproj @@ -0,0 +1,621 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LibreHardwareMonitor-0.9.4/InpOut/inpoutx64.sys b/LibreHardwareMonitor-0.9.4/InpOut/inpoutx64.sys new file mode 100644 index 0000000..4ddbcbb Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/InpOut/inpoutx64.sys differ diff --git a/LibreHardwareMonitor-0.9.4/InpOut/license.txt b/LibreHardwareMonitor-0.9.4/InpOut/license.txt new file mode 100644 index 0000000..e6b145a --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/license.txt @@ -0,0 +1,24 @@ +Copyright (c) <2003-2015> Phil Gibbons +Portions Copyright (c) <2000> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + + + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + + + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/InpOut/osversion.cpp b/LibreHardwareMonitor-0.9.4/InpOut/osversion.cpp new file mode 100644 index 0000000..b5e0ead --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/osversion.cpp @@ -0,0 +1,78 @@ +#include "stdafx.h" +#include "hwinterfacedrv.h" + +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); +typedef BOOL (WINAPI *LPFN_WOW64DISABLE) (PVOID*); +typedef BOOL (WINAPI *LPFN_WOW64REVERT) (PVOID); + +LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")),"IsWow64Process"); +LPFN_WOW64DISABLE fnWow64Disable = (LPFN_WOW64DISABLE)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64DisableWow64FsRedirection"); +LPFN_WOW64REVERT fnWow64Revert = (LPFN_WOW64REVERT)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64RevertWow64FsRedirection"); + +//Purpose: Return TRUE if we are running in WOW64 (i.e. a 32bit process on XP x64 edition) +BOOL _stdcall IsXP64Bit() +{ +#ifdef _M_X64 + return TRUE; //Urrr if its a x64 build of the DLL, we MUST be running on X64 nativly! +#endif + + BOOL bIsWow64 = FALSE; + if (NULL != fnIsWow64Process) + { + if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) + { + // handle error + } + } + return bIsWow64; +} + +BOOL DisableWOW64(PVOID* oldValue) +{ +#ifdef _M_X64 + return TRUE; // If were 64b under x64, we dont wanna do anything! +#endif + return fnWow64Disable(oldValue); +} + +BOOL RevertWOW64(PVOID* oldValue) +{ +#ifdef _M_X64 + return TRUE; // If were 64b under x64, we dont wanna do anything! +#endif + return fnWow64Revert (oldValue); +} + +int SystemVersion() +{ + OSVERSIONINFOEX osvi; + BOOL bOsVersionInfoEx; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) + { + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + + if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) + return 0; + } + + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + + return 2; //WINNT + + break; + + case VER_PLATFORM_WIN32_WINDOWS: + + return 1; //WIN9X + + break; + + } + return 0; +} diff --git a/LibreHardwareMonitor-0.9.4/InpOut/resource.h b/LibreHardwareMonitor-0.9.4/InpOut/resource.h new file mode 100644 index 0000000..3e0ae19 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/InpOut/resource.h @@ -0,0 +1,18 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by inpout32drv.rc +// +#define IDR_BIN1 101 +#define IDR_INPOUT32 101 +#define IDR_INPOUTX64 104 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/LibreHardwareMonitor-0.9.4/LICENSE b/LibreHardwareMonitor-0.9.4/LICENSE new file mode 100644 index 0000000..a612ad9 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor.sln b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor.sln new file mode 100644 index 0000000..7cf85aa --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29306.81 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreHardwareMonitorLib", "LibreHardwareMonitorLib\LibreHardwareMonitorLib.csproj", "{B0397530-545A-471D-BB74-027AE456DF1A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreHardwareMonitor", "LibreHardwareMonitor\LibreHardwareMonitor.csproj", "{F5E0C1F7-9E9B-46F2-AC88-8C9C1C923880}" + ProjectSection(ProjectDependencies) = postProject + {B0397530-545A-471D-BB74-027AE456DF1A} = {B0397530-545A-471D-BB74-027AE456DF1A} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aga.Controls", "Aga.Controls\Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Controls", "Controls", "{23F54DBD-8998-4E22-A4E4-60F4F77F9B65}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BAEC1DFE-5D1E-4CDB-8264-6C85B229D812}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.Build.props = Directory.Build.props + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0397530-545A-471D-BB74-027AE456DF1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0397530-545A-471D-BB74-027AE456DF1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0397530-545A-471D-BB74-027AE456DF1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0397530-545A-471D-BB74-027AE456DF1A}.Release|Any CPU.Build.0 = Release|Any CPU + {F5E0C1F7-9E9B-46F2-AC88-8C9C1C923880}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5E0C1F7-9E9B-46F2-AC88-8C9C1C923880}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5E0C1F7-9E9B-46F2-AC88-8C9C1C923880}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5E0C1F7-9E9B-46F2-AC88-8C9C1C923880}.Release|Any CPU.Build.0 = Release|Any CPU + {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 + GlobalSection(NestedProjects) = preSolution + {E73BB233-D88B-44A7-A98F-D71EE158381D} = {23F54DBD-8998-4E22-A4E4-60F4F77F9B65} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6A8EF661-2BD7-498F-8FB9-28182B3B0BE5} + EndGlobalSection +EndGlobal diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/LibreHardwareMonitor.csproj b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/LibreHardwareMonitor.csproj new file mode 100644 index 0000000..158ea57 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/LibreHardwareMonitor.csproj @@ -0,0 +1,77 @@ + + + WinExe + net472 + LibreHardwareMonitor + Libre Hardware Monitor + LibreHardwareMonitor + true + Resources\icon.ico + Resources\app.manifest + LibreHardwareMonitor.Program + true + ..\bin\$(Configuration)\ + latest + AnyCPU + + + full + + + none + + + + + + + + + + + + + + + AboutBox.cs + + + AuthForm.cs + + + MainForm.cs + + + ParameterForm.cs + + + InterfacePortForm.cs + + + + + AboutBox.cs + + + AuthForm.cs + + + MainForm.cs + + + ParameterForm.cs + + + InterfacePortForm.cs + + + + + + + + + + + + diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Program.cs b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Program.cs new file mode 100644 index 0000000..d4a3bda --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Program.cs @@ -0,0 +1,63 @@ +// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// Copyright (C) LibreHardwareMonitor and Contributors. +// Partial Copyright (C) Michael Möller and Contributors. +// All Rights Reserved. + +using System; +using System.IO; +using System.Windows.Forms; +using LibreHardwareMonitor.UI; + +namespace LibreHardwareMonitor; + +public static class Program +{ + [STAThread] + public static void Main() + { + if (!AllRequiredFilesAvailable()) + Environment.Exit(0); + + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + using (MainForm form = new MainForm()) + { + form.FormClosed += delegate + { + Application.Exit(); + }; + Application.Run(); + } + } + + private static bool IsFileAvailable(string fileName) + { + string path = Path.GetDirectoryName(Application.ExecutablePath) + Path.DirectorySeparatorChar; + if (!File.Exists(path + fileName)) + { + MessageBox.Show("The following file could not be found: " + fileName + + "\nPlease extract all files from the archive.", "Error", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + return true; + } + + private static bool AllRequiredFilesAvailable() + { + if (!IsFileAvailable("Aga.Controls.dll")) + return false; + + if (!IsFileAvailable("LibreHardwareMonitorLib.dll")) + return false; + + if (!IsFileAvailable("OxyPlot.dll")) + return false; + + if (!IsFileAvailable("OxyPlot.WindowsForms.dll")) + return false; + + return true; + } +} diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..5b5dab2 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000..ad3d634 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000..42ccba2 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000..5a46b47 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_e6e6e6_1x400.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 0000000..86c2baa Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_ffffff_1x400.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_ffffff_1x400.png new file mode 100644 index 0000000..e65ca12 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_glass_75_ffffff_1x400.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000..7c9fa6c Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_inset-soft_95_fef1ec_1x100.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_inset-soft_95_fef1ec_1x100.png new file mode 100644 index 0000000..0e05810 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-bg_inset-soft_95_fef1ec_1x100.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_222222_256x240.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000..b273ff1 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_222222_256x240.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_2e83ff_256x240.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000..09d1cdc Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_2e83ff_256x240.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_454545_256x240.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000..59bd45b Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_454545_256x240.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_888888_256x240.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000..6d02426 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_888888_256x240.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_cd0a0a_256x240.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000..2ab019b Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/images/ui-icons_cd0a0a_256x240.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/jquery-ui-1.8.16.custom.css b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/jquery-ui-1.8.16.custom.css new file mode 100644 index 0000000..7f50e04 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/custom-theme/jquery-ui-1.8.16.custom.css @@ -0,0 +1,351 @@ +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_75_ffffff_1x400.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_inset-soft_95_fef1ec_1x100.png) 50% bottom repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* + * jQuery UI Button 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Slider 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; } \ No newline at end of file diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/jquery.treeTable.css b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/jquery.treeTable.css new file mode 100644 index 0000000..81d8f0a --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/jquery.treeTable.css @@ -0,0 +1,47 @@ +/* jQuery treeTable stylesheet + * + * This file contains styles that are used to display the tree table. Each tree + * table is assigned the +treeTable+ class. + * ========================================================================= */ + +/* jquery.treeTable.collapsible + * ------------------------------------------------------------------------- */ +.treeTable tr td .expander { + background-position: left center; + background-repeat: no-repeat; + cursor: pointer; + padding: 0; + zoom: 1; /* IE7 Hack */ +} + +.treeTable tr.collapsed td .expander { + background-image: url(../images/toggle-expand-dark.png); +} + +.treeTable tr.expanded td .expander { + background-image: url(../images/toggle-collapse-dark.png); +} + +/* jquery.treeTable.sortable + * ------------------------------------------------------------------------- */ +.treeTable tr.selected, .treeTable tr.accept { + background-color: #3875d7; + color: #fff; +} + +.treeTable tr.collapsed.selected td .expander, .treeTable tr.collapsed.accept td .expander { + background-image: url(../images/toggle-expand-light.png); +} + +.treeTable tr.expanded.selected td .expander, .treeTable tr.expanded.accept td .expander { + background-image: url(../images/toggle-collapse-light.png); +} + +.treeTable .ui-draggable-dragging { + color: #000; + z-index: 1; +} + +/* Layout helper taken from jQuery UI. This way I don't have to require the + * full jQuery UI CSS to be loaded. */ +.ui-helper-hidden { display: none; } diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/ohm_web.css b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/ohm_web.css new file mode 100644 index 0000000..59bf28b --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/css/ohm_web.css @@ -0,0 +1,39 @@ +body { + font-size: 62.5%; +} + +table +{ + border-collapse:collapse; +} + +table, tr +{ + border: 1px solid #F0F0F0; +} + +td +{ + padding-right:10px; +} + +/* Site + -------------------------------- */ + +body { + font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif"; +} + +div.header { + padding:12px; + font-family: "Trebuchet MS", "Arial", "Helvetica", "Verdana", "sans-serif"; +} + +div.main { + clear:both; + padding:12px; + font-family: "Trebuchet MS", "Arial", "Helvetica", "Verdana", "sans-serif"; + /*font-size: 1.3em;*/ + /*line-height: 1.4em;*/ +} + diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/favicon.ico b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/favicon.ico new file mode 100644 index 0000000..0e17037 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/favicon.ico differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-collapse-dark.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-collapse-dark.png new file mode 100644 index 0000000..76577a5 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-collapse-dark.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-collapse-light.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-collapse-light.png new file mode 100644 index 0000000..ed1612f Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-collapse-light.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-expand-dark.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-expand-dark.png new file mode 100644 index 0000000..cfb42a4 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-expand-dark.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-expand-light.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-expand-light.png new file mode 100644 index 0000000..27b5234 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/toggle-expand-light.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/transparent.png b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/transparent.png new file mode 100644 index 0000000..d665e17 Binary files /dev/null and b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/images/transparent.png differ diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/index.html b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/index.html new file mode 100644 index 0000000..a3337b9 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/index.html @@ -0,0 +1,63 @@ + + + + + + Libre Hardware Monitor - Web Version + + + + + + + + + + + + + + + + + + + + +
+ + + + +  
     +
+
+ +
+ + + + + + + + + + +
SensorMinValueMax
+
+ + diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/js/jquery-1.7.2.js b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/js/jquery-1.7.2.js new file mode 100644 index 0000000..3774ff9 --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/js/jquery-1.7.2.js @@ -0,0 +1,9404 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Wed Mar 21 12:46:34 2012 -0700 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
" + + "" + + "
"; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and "); + }; + + if (jQueryTmplVersion > 0) { + jQuery['tmpl']['tag']['ko_code'] = { + open: "__.push($1 || '');" + }; + jQuery['tmpl']['tag']['ko_with'] = { + open: "with($1) {", + close: "} " + }; + } + }; + + ko.jqueryTmplTemplateEngine.prototype = new ko.templateEngine(); + + // Use this one by default *only if jquery.tmpl is referenced* + var jqueryTmplTemplateEngineInstance = new ko.jqueryTmplTemplateEngine(); + if (jqueryTmplTemplateEngineInstance.jQueryTmplVersion > 0) + ko.setTemplateEngine(jqueryTmplTemplateEngineInstance); + + ko.exportSymbol('jqueryTmplTemplateEngine', ko.jqueryTmplTemplateEngine); +})(); +}); +})(window,document,navigator); diff --git a/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/js/knockout-2.1.0.min.js b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/js/knockout-2.1.0.min.js new file mode 100644 index 0000000..107026d --- /dev/null +++ b/LibreHardwareMonitor-0.9.4/LibreHardwareMonitor/Resources/Web/js/knockout-2.1.0.min.js @@ -0,0 +1,86 @@ +// Knockout JavaScript library v2.1.0 +// (c) Steven Sanderson - http://knockoutjs.com/ +// License: MIT (http://www.opensource.org/licenses/mit-license.php) + +(function(window,document,navigator,undefined){ +function m(w){throw w;}var n=void 0,p=!0,s=null,t=!1;function A(w){return function(){return w}};function E(w){function B(b,c,d){d&&c!==a.k.r(b)&&a.k.S(b,c);c!==a.k.r(b)&&a.a.va(b,"change")}var a="undefined"!==typeof w?w:{};a.b=function(b,c){for(var d=b.split("."),f=a,g=0;g",c[0];);return 4a.a.j(c,b[e])&&c.push(b[e]);return c},T:function(a,b){for(var a=a||[],c=[], +e=0,f=a.length;ea.length?t:a.substring(0,b.length)===b},eb:function(a,b){for(var c="return ("+a+")",e=0;e",""]||!d.indexOf("",""]||(!d.indexOf("",""]||[0,"",""];b="ignored
"+d[1]+b+d[2]+"
";for("function"==typeof window.innerShiv?c.appendChild(window.innerShiv(b)):c.innerHTML=b;d[0]--;)c=c.lastChild;c=a.a.L(c.lastChild.childNodes)}return c}; +a.a.Y=function(b,c){a.a.ga(b);if(c!==s&&c!==n)if("string"!=typeof c&&(c=c.toString()),"undefined"!=typeof jQuery)jQuery(b).html(c);else for(var d=a.a.pa(c),f=0;f"},Va:function(a,b){var c=d[a];c===n&&m(Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized."));try{return c.apply(s,b||[]),p}finally{delete d[a]}},Wa:function(b,d){var e=[];c(b,e);for(var h=0,j=e.length;hc;c++)b=b();return b})};a.toJSON=function(b,c,e){b=a.Ta(b);return a.a.sa(b,c,e)}})();a.b("toJS",a.Ta);a.b("toJSON",a.toJSON);(function(){a.k={r:function(b){switch(a.a.o(b)){case "option":return b.__ko__hasDomDataOptionValue__===p?a.a.f.get(b,a.c.options.oa):b.getAttribute("value");case "select":return 0<=b.selectedIndex?a.k.r(b.options[b.selectedIndex]):n;default:return b.value}},S:function(b,c){switch(a.a.o(b)){case "option":switch(typeof c){case "string":a.a.f.set(b,a.c.options.oa, +n);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.f.set(b,a.c.options.oa,c),b.__ko__hasDomDataOptionValue__=p,b.value="number"===typeof c?c:""}break;case "select":for(var d=b.options.length-1;0<=d;d--)if(a.k.r(b.options[d])==c){b.selectedIndex=d;break}break;default:if(c===s||c===n)c="";b.value=c}}}})();a.b("selectExtensions",a.k);a.b("selectExtensions.readValue",a.k.r);a.b("selectExtensions.writeValue",a.k.S);a.g=function(){function b(a,b){for(var d= +s;a!=d;)d=a,a=a.replace(c,function(a,c){return b[c]});return a}var c=/\@ko_token_(\d+)\@/g,d=/^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$/i,f=["true","false"];return{D:[],W:function(c){var e=a.a.w(c);if(3>e.length)return[];"{"===e.charAt(0)&&(e=e.substring(1,e.length-1));for(var c=[],d=s,f,k=0;k$/: +/^\s*ko\s+(.*\:.*)\s*$/,h=g?/^<\!--\s*\/ko\s*--\>$/:/^\s*\/ko\s*$/,j={ul:p,ol:p};a.e={C:{},childNodes:function(a){return b(a)?d(a):a.childNodes},ha:function(c){if(b(c))for(var c=a.e.childNodes(c),e=0,d=c.length;e"),t))}};a.c.uniqueName.gb=0;a.c.checked={init:function(b,c,d){a.a.n(b,"click",function(){var f;if("checkbox"==b.type)f=b.checked;else if("radio"==b.type&&b.checked)f=b.value;else return;var g=c();"checkbox"==b.type&&a.a.d(g)instanceof Array?(f=a.a.j(a.a.d(g),b.value), +b.checked&&0>f?g.push(b.value):!b.checked&&0<=f&&g.splice(f,1)):a.g.$(g,d,"checked",f,p)});"radio"==b.type&&!b.name&&a.c.uniqueName.init(b,A(p))},update:function(b,c){var d=a.a.d(c());"checkbox"==b.type?b.checked=d instanceof Array?0<=a.a.j(d,b.value):d:"radio"==b.type&&(b.checked=b.value==d)}};var F={"class":"className","for":"htmlFor"};a.c.attr={update:function(b,c){var d=a.a.d(c())||{},f;for(f in d)if("string"==typeof f){var g=a.a.d(d[f]),e=g===t||g===s||g===n;e&&b.removeAttribute(f);8>=a.a.ja&& +f in F?(f=F[f],e?b.removeAttribute(f):b[f]=g):e||b.setAttribute(f,g.toString())}}};a.c.hasfocus={init:function(b,c,d){function f(b){var e=c();a.g.$(e,d,"hasfocus",b,p)}a.a.n(b,"focus",function(){f(p)});a.a.n(b,"focusin",function(){f(p)});a.a.n(b,"blur",function(){f(t)});a.a.n(b,"focusout",function(){f(t)})},update:function(b,c){var d=a.a.d(c());d?b.focus():b.blur();a.a.va(b,d?"focusin":"focusout")}};a.c["with"]={p:function(b){return function(){var c=b();return{"if":c,data:c,templateEngine:a.q.K}}}, +init:function(b,c){return a.c.template.init(b,a.c["with"].p(c))},update:function(b,c,d,f,g){return a.c.template.update(b,a.c["with"].p(c),d,f,g)}};a.g.D["with"]=t;a.e.C["with"]=p;a.c["if"]={p:function(b){return function(){return{"if":b(),templateEngine:a.q.K}}},init:function(b,c){return a.c.template.init(b,a.c["if"].p(c))},update:function(b,c,d,f,g){return a.c.template.update(b,a.c["if"].p(c),d,f,g)}};a.g.D["if"]=t;a.e.C["if"]=p;a.c.ifnot={p:function(b){return function(){return{ifnot:b(),templateEngine:a.q.K}}}, +init:function(b,c){return a.c.template.init(b,a.c.ifnot.p(c))},update:function(b,c,d,f,g){return a.c.template.update(b,a.c.ifnot.p(c),d,f,g)}};a.g.D.ifnot=t;a.e.C.ifnot=p;a.c.foreach={p:function(b){return function(){var c=a.a.d(b());return!c||"number"==typeof c.length?{foreach:c,templateEngine:a.q.K}:{foreach:c.data,includeDestroyed:c.includeDestroyed,afterAdd:c.afterAdd,beforeRemove:c.beforeRemove,afterRender:c.afterRender,templateEngine:a.q.K}}},init:function(b,c){return a.c.template.init(b,a.c.foreach.p(c))}, +update:function(b,c,d,f,g){return a.c.template.update(b,a.c.foreach.p(c),d,f,g)}};a.g.D.foreach=t;a.e.C.foreach=p;a.t=function(){};a.t.prototype.renderTemplateSource=function(){m(Error("Override renderTemplateSource"))};a.t.prototype.createJavaScriptEvaluatorBlock=function(){m(Error("Override createJavaScriptEvaluatorBlock"))};a.t.prototype.makeTemplateSource=function(b,c){if("string"==typeof b){var c=c||document,d=c.getElementById(b);d||m(Error("Cannot find template with ID "+b));return new a.l.i(d)}if(1== +b.nodeType||8==b.nodeType)return new a.l.M(b);m(Error("Unknown template type: "+b))};a.t.prototype.renderTemplate=function(a,c,d,f){return this.renderTemplateSource(this.makeTemplateSource(a,f),c,d)};a.t.prototype.isTemplateRewritten=function(a,c){return this.allowTemplateRewriting===t||!(c&&c!=document)&&this.V&&this.V[a]?p:this.makeTemplateSource(a,c).data("isRewritten")};a.t.prototype.rewriteTemplate=function(a,c,d){var f=this.makeTemplateSource(a,d),c=c(f.text());f.text(c);f.data("isRewritten", +p);!(d&&d!=document)&&"string"==typeof a&&(this.V=this.V||{},this.V[a]=p)};a.b("templateEngine",a.t);a.Z=function(){function b(b,c,e){for(var b=a.g.W(b),d=a.g.D,j=0;j/g;return{mb:function(b,c,e){c.isTemplateRewritten(b,e)||c.rewriteTemplate(b,function(b){return a.Z.zb(b,c)},e)},zb:function(a,g){return a.replace(c,function(a,c,d,f,i,l,q){return b(q,c,g)}).replace(d,function(a,c){return b(c,"<\!-- ko --\>",g)})},Za:function(b){return a.s.na(function(c, +e){c.nextSibling&&a.ya(c.nextSibling,b,e)})}}}();a.b("templateRewriting",a.Z);a.b("templateRewriting.applyMemoizedBindingsToNextSibling",a.Z.Za);(function(){a.l={};a.l.i=function(a){this.i=a};a.l.i.prototype.text=function(){var b=a.a.o(this.i),b="script"===b?"text":"textarea"===b?"value":"innerHTML";if(0==arguments.length)return this.i[b];var c=arguments[0];"innerHTML"===b?a.a.Y(this.i,c):this.i[b]=c};a.l.i.prototype.data=function(b){if(1===arguments.length)return a.a.f.get(this.i,"templateSourceData_"+ +b);a.a.f.set(this.i,"templateSourceData_"+b,arguments[1])};a.l.M=function(a){this.i=a};a.l.M.prototype=new a.l.i;a.l.M.prototype.text=function(){if(0==arguments.length){var b=a.a.f.get(this.i,"__ko_anon_template__")||{};b.ua===n&&b.da&&(b.ua=b.da.innerHTML);return b.ua}a.a.f.set(this.i,"__ko_anon_template__",{ua:arguments[0]})};a.l.i.prototype.nodes=function(){if(0==arguments.length)return(a.a.f.get(this.i,"__ko_anon_template__")||{}).da;a.a.f.set(this.i,"__ko_anon_template__",{da:arguments[0]})}; +a.b("templateSources",a.l);a.b("templateSources.domElement",a.l.i);a.b("templateSources.anonymousTemplate",a.l.M)})();(function(){function b(b,c,d){for(var f,c=a.e.nextSibling(c);b&&(f=b)!==c;)b=a.e.nextSibling(f),(1===f.nodeType||8===f.nodeType)&&d(f)}function c(c,d){if(c.length){var f=c[0],g=c[c.length-1];b(f,g,function(b){a.xa(d,b)});b(f,g,function(b){a.s.Wa(b,[d])})}}function d(a){return a.nodeType?a:0a.a.ja)&&b.nodes?b.nodes():s; +if(c)return a.a.L(c.cloneNode(p).childNodes);b=b.text();return a.a.pa(b)};a.q.K=new a.q;a.ra(a.q.K);a.b("nativeTemplateEngine",a.q);(function(){a.ma=function(){var a=this.vb=function(){if("undefined"==typeof jQuery||!jQuery.tmpl)return 0;try{if(0<=jQuery.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,f,g){g=g||{};2>a&&m(Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later."));var e=b.data("precompiled"); +e||(e=b.text()||"",e=jQuery.template(s,"{{ko_with $item.koBindingContext}}"+e+"{{/ko_with}}"),b.data("precompiled",e));b=[f.$data];f=jQuery.extend({koBindingContext:f},g.templateOptions);f=jQuery.tmpl(e,b,f);f.appendTo(document.createElement("div"));jQuery.fragments={};return f};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){document.write("