mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-01 12:20:56 +00:00
Initial commit of existing code.
* All renderdoc code up to this point was written by me, history is available by request
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
partial class ConstantBufferPreviewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
TreelistView.TreeListColumn treeListColumn1 = ((TreelistView.TreeListColumn)(new TreelistView.TreeListColumn("VarName", "Name")));
|
||||
TreelistView.TreeListColumn treeListColumn2 = ((TreelistView.TreeListColumn)(new TreelistView.TreeListColumn("VarValue", "Value")));
|
||||
TreelistView.TreeListColumn treeListColumn3 = ((TreelistView.TreeListColumn)(new TreelistView.TreeListColumn("VarType", "Type")));
|
||||
this.slotLabel = new System.Windows.Forms.Label();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.variables = new TreelistView.TreeListView();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.variables)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// slotLabel
|
||||
//
|
||||
this.slotLabel.AutoSize = true;
|
||||
this.slotLabel.Location = new System.Drawing.Point(3, 0);
|
||||
this.slotLabel.Name = "slotLabel";
|
||||
this.slotLabel.Padding = new System.Windows.Forms.Padding(5);
|
||||
this.slotLabel.Size = new System.Drawing.Size(10, 23);
|
||||
this.slotLabel.TabIndex = 0;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(19, 0);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Padding = new System.Windows.Forms.Padding(5);
|
||||
this.nameLabel.Size = new System.Drawing.Size(10, 23);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.slotLabel, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.nameLabel, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.variables, 0, 1);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(499, 357);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// variables
|
||||
//
|
||||
treeListColumn1.AutoSizeMinSize = 0;
|
||||
treeListColumn1.Width = 175;
|
||||
treeListColumn2.AutoSize = true;
|
||||
treeListColumn2.AutoSizeMinSize = 0;
|
||||
treeListColumn2.Width = 50;
|
||||
treeListColumn3.AutoSizeMinSize = 0;
|
||||
treeListColumn3.Width = 50;
|
||||
this.variables.Columns.AddRange(new TreelistView.TreeListColumn[] {
|
||||
treeListColumn1,
|
||||
treeListColumn2,
|
||||
treeListColumn3});
|
||||
this.variables.ColumnsOptions.LeftMargin = 0;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.variables, 2);
|
||||
this.variables.Cursor = System.Windows.Forms.Cursors.Arrow;
|
||||
this.variables.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.variables.Location = new System.Drawing.Point(3, 26);
|
||||
this.variables.Name = "variables";
|
||||
this.variables.RowOptions.ShowHeader = false;
|
||||
this.variables.Size = new System.Drawing.Size(493, 328);
|
||||
this.variables.TabIndex = 2;
|
||||
this.variables.Text = "treeListView1";
|
||||
this.variables.KeyDown += new System.Windows.Forms.KeyEventHandler(this.variables_KeyDown);
|
||||
//
|
||||
// ConstantBufferPreviewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Name = "ConstantBufferPreviewer";
|
||||
this.Size = new System.Drawing.Size(499, 357);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.variables)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private TreelistView.TreeListView variables;
|
||||
private System.Windows.Forms.Label slotLabel;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using renderdocui.Code;
|
||||
using renderdoc;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
public partial class ConstantBufferPreviewer : UserControl, ILogViewerForm
|
||||
{
|
||||
private Core m_Core;
|
||||
|
||||
public ConstantBufferPreviewer(Core c, ShaderStageType stage, UInt32 slot)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
m_Core = c;
|
||||
Stage = stage;
|
||||
Slot = slot;
|
||||
shader = m_Core.CurPipelineState.GetShader(stage);
|
||||
UpdateLabels();
|
||||
|
||||
uint offs = 0;
|
||||
m_Core.CurPipelineState.GetConstantBuffer(Stage, Slot, out cbuffer, out offs);
|
||||
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
|
||||
{
|
||||
SetVariables(r.GetCBufferVariableContents(shader, Slot, cbuffer, offs));
|
||||
});
|
||||
|
||||
m_Core.AddLogViewer(this);
|
||||
}
|
||||
|
||||
private static List<DockContent> m_Docks = new List<DockContent>();
|
||||
|
||||
public static DockContent Has(ShaderStageType stage, UInt32 slot)
|
||||
{
|
||||
foreach (var d in m_Docks)
|
||||
{
|
||||
ConstantBufferPreviewer cb = d.Controls[0] as ConstantBufferPreviewer;
|
||||
|
||||
if(cb.Stage == stage && cb.Slot == slot)
|
||||
return cb.Parent as DockContent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ShowDock(DockContent dock, DockPane pane, DockAlignment align, double proportion)
|
||||
{
|
||||
dock.FormClosed += new FormClosedEventHandler(dock_FormClosed);
|
||||
|
||||
if (m_Docks.Count > 0)
|
||||
dock.Show(m_Docks[0].Pane, m_Docks[0]);
|
||||
else
|
||||
dock.Show(pane, align, proportion);
|
||||
|
||||
m_Docks.Add(dock);
|
||||
}
|
||||
|
||||
static void dock_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
DockContent p = sender as DockContent;
|
||||
m_Docks.Remove(p);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
|
||||
m_Core.RemoveLogViewer(this);
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
public void OnLogfileClosed()
|
||||
{
|
||||
variables.BeginUpdate();
|
||||
variables.Nodes.Clear();
|
||||
|
||||
variables.EndUpdate();
|
||||
variables.Invalidate();
|
||||
}
|
||||
|
||||
public void OnLogfileLoaded()
|
||||
{
|
||||
variables.BeginUpdate();
|
||||
variables.Nodes.Clear();
|
||||
|
||||
variables.EndUpdate();
|
||||
variables.Invalidate();
|
||||
}
|
||||
|
||||
private void AddVariables(TreelistView.NodeCollection root, ShaderVariable[] vars)
|
||||
{
|
||||
foreach (var v in vars)
|
||||
{
|
||||
TreelistView.Node n = root.Add(new TreelistView.Node(new object[] { v.name, v, v.TypeString() }));
|
||||
|
||||
if (v.rows > 1)
|
||||
{
|
||||
for (int i = 0; i < v.rows; i++)
|
||||
{
|
||||
n.Nodes.Add(new TreelistView.Node(new object[] { String.Format("{0}.row{1}", v.name, i), v.Row(i), v.RowTypeString() }));
|
||||
}
|
||||
}
|
||||
|
||||
if (v.members.Length > 0)
|
||||
{
|
||||
AddVariables(n.Nodes, v.members);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetVariables(ShaderVariable[] vars)
|
||||
{
|
||||
if (variables.InvokeRequired)
|
||||
{
|
||||
this.BeginInvoke(new Action(() => { SetVariables(vars); }));
|
||||
return;
|
||||
}
|
||||
|
||||
variables.BeginUpdate();
|
||||
variables.Nodes.Clear();
|
||||
|
||||
if(vars != null && vars.Length > 0)
|
||||
AddVariables(variables.Nodes, vars);
|
||||
|
||||
variables.EndUpdate();
|
||||
variables.Invalidate();
|
||||
}
|
||||
|
||||
public void OnEventSelected(UInt32 frameID, UInt32 eventID)
|
||||
{
|
||||
uint offs = 0;
|
||||
m_Core.CurPipelineState.GetConstantBuffer(Stage, Slot, out cbuffer, out offs);
|
||||
|
||||
shader = m_Core.CurPipelineState.GetShader(Stage);
|
||||
var reflection = m_Core.CurPipelineState.GetShaderReflection(Stage);
|
||||
|
||||
UpdateLabels();
|
||||
|
||||
if (reflection == null || reflection.ConstantBlocks.Length <= Slot)
|
||||
{
|
||||
SetVariables(null);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
|
||||
{
|
||||
SetVariables(r.GetCBufferVariableContents(shader, Slot, cbuffer, offs));
|
||||
});
|
||||
}
|
||||
|
||||
private string BufferName = "";
|
||||
|
||||
private ResourceId cbuffer;
|
||||
private ResourceId shader;
|
||||
private ShaderStageType Stage;
|
||||
private UInt32 Slot = 0;
|
||||
|
||||
public override string Text
|
||||
{
|
||||
get
|
||||
{
|
||||
return String.Format("{0} CB {1}", Stage.ToString(), Slot);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLabels()
|
||||
{
|
||||
BufferName = "";
|
||||
|
||||
bool needName = true;
|
||||
|
||||
foreach (var b in m_Core.CurBuffers)
|
||||
{
|
||||
if (b.ID == cbuffer)
|
||||
{
|
||||
BufferName = b.name;
|
||||
if(b.customName)
|
||||
needName = false;
|
||||
}
|
||||
}
|
||||
|
||||
var reflection = m_Core.CurPipelineState.GetShaderReflection(Stage);
|
||||
|
||||
if (reflection != null)
|
||||
{
|
||||
if (needName &&
|
||||
Slot < reflection.ConstantBlocks.Length &&
|
||||
reflection.ConstantBlocks[Slot].name != "")
|
||||
BufferName = "<" + reflection.ConstantBlocks[Slot].name + ">";
|
||||
}
|
||||
|
||||
nameLabel.Text = BufferName;
|
||||
|
||||
slotLabel.Text = Stage.ToString();
|
||||
slotLabel.Text += " Shader Slot " + Slot;
|
||||
}
|
||||
|
||||
private void variables_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.C && e.Control)
|
||||
{
|
||||
int[] width = new int[] { 0, 0, 0 };
|
||||
|
||||
foreach (var n in variables.NodesSelection)
|
||||
{
|
||||
width[0] = Math.Max(width[0], n[0].ToString().Length);
|
||||
width[1] = Math.Max(width[1], n[1].ToString().Length);
|
||||
width[2] = Math.Max(width[2], n[2].ToString().Length);
|
||||
}
|
||||
|
||||
width[0] = Math.Min(50, width[0]);
|
||||
width[1] = Math.Min(50, width[1]);
|
||||
width[2] = Math.Min(50, width[2]);
|
||||
|
||||
string fmt = "{0,-" + width[0] + "} {1,-" + width[1] + "} {2,-" + width[2] + "}" + Environment.NewLine;
|
||||
|
||||
string text = "";
|
||||
foreach (var n in variables.NodesSelection)
|
||||
{
|
||||
text += string.Format(fmt, n[0], n[1], n[2]);
|
||||
}
|
||||
|
||||
Clipboard.SetText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
partial class DoubleClickSplitter
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
public partial class DoubleClickSplitter : SplitContainer
|
||||
{
|
||||
public DoubleClickSplitter()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
SplitterMoving += new SplitterCancelEventHandler(OnSplitterMoving);
|
||||
}
|
||||
|
||||
private int m_PanelMinsize = 0;
|
||||
private int m_SplitterDistance = 0;
|
||||
|
||||
private bool m_Panel1Collapse = true;
|
||||
|
||||
[Description("If the first panel should be the one to collapse"), Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "true")]
|
||||
public bool Panel1Collapse { get { return m_Panel1Collapse; } set { m_Panel1Collapse = value; } }
|
||||
|
||||
private bool m_Collapsed = false;
|
||||
[Browsable(false)]
|
||||
public bool Collapsed
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Collapsed;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_Collapsed != value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
m_PanelMinsize = Panel1Collapse ? Panel1MinSize : Panel2MinSize;
|
||||
m_SplitterDistance = SplitterDistance;
|
||||
|
||||
if (Panel1Collapse)
|
||||
{
|
||||
Panel1MinSize = 0;
|
||||
SplitterDistance = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Panel2MinSize = 0;
|
||||
SplitterDistance = 10000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Panel1Collapse)
|
||||
Panel1MinSize = m_PanelMinsize;
|
||||
else
|
||||
Panel2MinSize = m_PanelMinsize;
|
||||
|
||||
SplitterDistance = m_SplitterDistance;
|
||||
}
|
||||
}
|
||||
|
||||
m_Collapsed = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
|
||||
try
|
||||
{
|
||||
if (m_Collapsed && Panel1Collapse)
|
||||
SplitterDistance = Panel1MinSize;
|
||||
else if (m_Collapsed && !Panel1Collapse)
|
||||
{
|
||||
if(Orientation == Orientation.Vertical)
|
||||
SplitterDistance = Height - Panel2MinSize;
|
||||
else if(Orientation == Orientation.Horizontal)
|
||||
SplitterDistance = Width - Panel2MinSize;
|
||||
}
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
// non fatal
|
||||
}
|
||||
|
||||
// arrow
|
||||
{
|
||||
var arrow_centre = new Point(SplitterRectangle.X + SplitterRectangle.Width / 2, SplitterRectangle.Y + SplitterRectangle.Height / 2);
|
||||
|
||||
var oldmode = e.Graphics.SmoothingMode;
|
||||
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
||||
|
||||
Point[] dots = null;
|
||||
|
||||
using(var brush = new SolidBrush(ForeColor))
|
||||
{
|
||||
int dot_diameter = 0;
|
||||
|
||||
if (Orientation == Orientation.Horizontal)
|
||||
{
|
||||
dot_diameter = SplitterRectangle.Height - Math.Max(0, SplitterRectangle.Height / 4);
|
||||
|
||||
var arrow_size = new Size(SplitterRectangle.Height * 2, dot_diameter);
|
||||
var arrow_pos = new Point(arrow_centre.X - arrow_size.Width / 2, arrow_centre.Y - arrow_size.Height / 2);
|
||||
|
||||
if ((Panel1Collapse && !Collapsed) || (!Panel1Collapse && Collapsed))
|
||||
{
|
||||
e.Graphics.FillPolygon(brush, new Point[] {
|
||||
new Point(arrow_pos.X, arrow_pos.Y + arrow_size.Height),
|
||||
new Point(arrow_pos.X +arrow_size.Width, arrow_pos.Y + arrow_size.Height),
|
||||
new Point(arrow_pos.X + arrow_size.Width/2, arrow_pos.Y),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Graphics.FillPolygon(brush, new Point[] {
|
||||
new Point(arrow_pos.X, arrow_pos.Y),
|
||||
new Point(arrow_pos.X +arrow_size.Width, arrow_pos.Y),
|
||||
new Point(arrow_pos.X + arrow_size.Width/2, arrow_pos.Y + arrow_size.Height),
|
||||
});
|
||||
}
|
||||
|
||||
dots = new Point[] {
|
||||
new Point(arrow_centre.X - SplitterRectangle.Width/4 - (int)(dot_diameter*1.5), arrow_centre.Y),
|
||||
new Point(arrow_centre.X - SplitterRectangle.Width/4, arrow_centre.Y),
|
||||
new Point(arrow_centre.X - SplitterRectangle.Width/4 + (int)(dot_diameter*1.5), arrow_centre.Y),
|
||||
|
||||
new Point(arrow_centre.X + SplitterRectangle.Width/4 - (int)(dot_diameter*1.5), arrow_centre.Y),
|
||||
new Point(arrow_centre.X + SplitterRectangle.Width/4, arrow_centre.Y),
|
||||
new Point(arrow_centre.X + SplitterRectangle.Width/4 + (int)(dot_diameter*1.5), arrow_centre.Y),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
dot_diameter = SplitterRectangle.Width - Math.Max(0, SplitterRectangle.Width / 4);
|
||||
|
||||
var arrow_size = new Size(dot_diameter, SplitterRectangle.Width * 2);
|
||||
var arrow_pos = new Point(arrow_centre.X - arrow_size.Width / 2, arrow_centre.Y - arrow_size.Height / 2);
|
||||
|
||||
if ((Panel1Collapse && !Collapsed) || (!Panel1Collapse && Collapsed))
|
||||
{
|
||||
e.Graphics.FillPolygon(brush, new Point[] {
|
||||
new Point(arrow_pos.X + arrow_size.Width, arrow_pos.Y),
|
||||
new Point(arrow_pos.X +arrow_size.Width, arrow_pos.Y + arrow_size.Height),
|
||||
new Point(arrow_pos.X, arrow_pos.Y + arrow_size.Height/2),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Graphics.FillPolygon(brush, new Point[] {
|
||||
new Point(arrow_pos.X, arrow_pos.Y),
|
||||
new Point(arrow_pos.X, arrow_pos.Y +arrow_size.Height),
|
||||
new Point(arrow_pos.X + arrow_size.Width, arrow_pos.Y + arrow_size.Height/2),
|
||||
});
|
||||
}
|
||||
|
||||
dots = new Point[] {
|
||||
new Point(arrow_centre.X, arrow_centre.Y - SplitterRectangle.Height/4 - (int)(dot_diameter*1.5)),
|
||||
new Point(arrow_centre.X, arrow_centre.Y - SplitterRectangle.Height/4),
|
||||
new Point(arrow_centre.X, arrow_centre.Y - SplitterRectangle.Height/4 + (int)(dot_diameter*1.5)),
|
||||
|
||||
new Point(arrow_centre.X, arrow_centre.Y + SplitterRectangle.Height/4 - (int)(dot_diameter*1.5)),
|
||||
new Point(arrow_centre.X, arrow_centre.Y + SplitterRectangle.Height/4),
|
||||
new Point(arrow_centre.X, arrow_centre.Y + SplitterRectangle.Height/4 + (int)(dot_diameter*1.5)),
|
||||
};
|
||||
}
|
||||
|
||||
if (dots != null)
|
||||
{
|
||||
foreach (var d in dots)
|
||||
{
|
||||
var rect = new Rectangle(new Point(d.X - dot_diameter / 2, d.Y - dot_diameter / 2), new Size(dot_diameter, dot_diameter));
|
||||
|
||||
e.Graphics.FillPie(brush, rect, 0, 360.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.Graphics.SmoothingMode = oldmode;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDoubleClick(EventArgs e)
|
||||
{
|
||||
if (SplitterRectangle.Contains(PointToClient(Control.MousePosition)))
|
||||
{
|
||||
Collapsed = !Collapsed;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnDoubleClick(e);
|
||||
}
|
||||
|
||||
void OnSplitterMoving(object sender, SplitterCancelEventArgs e)
|
||||
{
|
||||
if (Collapsed)
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
public class NoScrollPanel : Panel
|
||||
{
|
||||
public MouseEventHandler MouseWheelHandler = null;
|
||||
public KeyEventHandler KeyHandler = null;
|
||||
|
||||
public NoScrollPanel() { }
|
||||
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
if (MouseWheelHandler != null)
|
||||
MouseWheelHandler(this, e);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
if (Focused && KeyHandler != null)
|
||||
{
|
||||
var args = new KeyEventArgs(keyData);
|
||||
KeyHandler(this, args);
|
||||
if(args.Handled)
|
||||
return true;
|
||||
}
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
public bool Painting = false;
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs pevent)
|
||||
{
|
||||
if (Controls.Count == 0 && !Painting)
|
||||
{
|
||||
pevent.Graphics.Clear(BackColor);
|
||||
}
|
||||
else if (Controls.Count == 1)
|
||||
{
|
||||
var pos = Controls[0].Location;
|
||||
var size = Controls[0].Size;
|
||||
|
||||
using (var brush = new SolidBrush(BackColor))
|
||||
{
|
||||
var rightRect = new Rectangle(pos.X + size.Width, 0, ClientRectangle.Width - (pos.X + size.Width), ClientRectangle.Height);
|
||||
var leftRect = new Rectangle(0, 0, pos.X, ClientRectangle.Height);
|
||||
var topRect = new Rectangle(pos.X, 0, size.Width, pos.Y);
|
||||
var bottomRect = new Rectangle(pos.X, pos.Y + size.Height, size.Width, ClientRectangle.Height - (pos.Y + size.Height));
|
||||
|
||||
pevent.Graphics.FillRectangle(brush, topRect);
|
||||
pevent.Graphics.FillRectangle(brush, bottomRect);
|
||||
pevent.Graphics.FillRectangle(brush, leftRect);
|
||||
pevent.Graphics.FillRectangle(brush, rightRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Point ScrollToControl(Control activeControl)
|
||||
{
|
||||
// Returning the current location prevents the panel from
|
||||
// scrolling to the active control when the panel loses and regains focus
|
||||
return this.DisplayRectangle.Location;
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
partial class PipelineFlowchart
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// PipelineFlowchart
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Transparent;
|
||||
this.Name = "PipelineFlowchart";
|
||||
this.Size = new System.Drawing.Size(988, 229);
|
||||
this.Paint += new System.Windows.Forms.PaintEventHandler(this.PipelineFlowchart_Paint);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
public partial class PipelineFlowchart : UserControl
|
||||
{
|
||||
public PipelineFlowchart()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.DoubleBuffered = true;
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
|
||||
}
|
||||
|
||||
public void SetStages(KeyValuePair<string, string>[] stages)
|
||||
{
|
||||
m_StageNames = stages;
|
||||
m_StagesEnabled = new bool[stages.Length];
|
||||
m_StageFlows = new bool[stages.Length];
|
||||
for(int i=0; i < stages.Length; i++)
|
||||
m_StageFlows[i] = true;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
private static readonly object SelectedStageChangedEvent = new object();
|
||||
|
||||
[Description("Event raised when the selected pipeline stage is changed."), Category("Behavior")]
|
||||
public event EventHandler<EventArgs> SelectedStageChanged
|
||||
{
|
||||
add { Events.AddHandler(SelectedStageChangedEvent, value); }
|
||||
remove { Events.RemoveHandler(SelectedStageChangedEvent, value); }
|
||||
}
|
||||
protected virtual void OnSelectedStageChanged(EventArgs e)
|
||||
{
|
||||
EventHandler<EventArgs> handler = (EventHandler<EventArgs>)Events[SelectedStageChangedEvent];
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Data Properties
|
||||
|
||||
private bool[] m_StagesEnabled = null;
|
||||
private bool[] m_StageFlows = null;
|
||||
private KeyValuePair<string, string>[] m_StageNames = null;
|
||||
|
||||
public void SetStagesEnabled(bool[] enabled)
|
||||
{
|
||||
if (m_StagesEnabled != null && enabled.Length == m_StagesEnabled.Length)
|
||||
m_StagesEnabled = enabled;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
public void IsolateStage(int index)
|
||||
{
|
||||
if (m_StageNames != null && index >= 0 && index < m_StageNames.Length)
|
||||
m_StageFlows[index] = false;
|
||||
}
|
||||
|
||||
private bool IsStageEnabled(int index)
|
||||
{
|
||||
return m_StagesEnabled != null && m_StagesEnabled[index];
|
||||
}
|
||||
|
||||
private int m_HoverStage = -1;
|
||||
private int m_SelectedStage = 0;
|
||||
|
||||
[Browsable(false)]
|
||||
public int SelectedStage
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SelectedStage;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value >= 0 && m_StageNames != null && value < m_StageNames.Length)
|
||||
{
|
||||
m_SelectedStage = value;
|
||||
Invalidate();
|
||||
|
||||
OnSelectedStageChanged(new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constants and positions/dimensions
|
||||
|
||||
const int BoxBorderWidth = 3;
|
||||
const int MinBoxDimension = 25;
|
||||
const int MaxBoxCornerRadius = 20;
|
||||
const float BoxCornerRadiusFraction = 1.0f / 6.0f;
|
||||
const float ArrowHeadSize = 6.0f;
|
||||
const int MinBoxMargin = 4;
|
||||
const int BoxLabelMargin = 8;
|
||||
const float BoxMarginFraction = 0.02f;
|
||||
|
||||
private Rectangle TotalAreaRect
|
||||
{
|
||||
get
|
||||
{
|
||||
Rectangle rect = ClientRectangle;
|
||||
|
||||
rect.Inflate(-1, -1);
|
||||
|
||||
rect.X += Padding.Left;
|
||||
rect.Width -= Padding.Left + Padding.Right;
|
||||
|
||||
rect.Y += Padding.Top;
|
||||
rect.Height -= Padding.Top + Padding.Bottom;
|
||||
|
||||
rect.Inflate(-BoxBorderWidth, -BoxBorderWidth);
|
||||
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
|
||||
private float BoxMargin
|
||||
{
|
||||
get
|
||||
{
|
||||
float margin = Math.Max(TotalAreaRect.Width, TotalAreaRect.Height) * BoxMarginFraction;
|
||||
|
||||
margin = Math.Max(MinBoxMargin, margin);
|
||||
|
||||
return margin;
|
||||
}
|
||||
}
|
||||
|
||||
private int NumGaps { get { return m_StageNames == null ? 1 : m_StageNames.Length - 1; } }
|
||||
private int NumItems { get { return m_StageNames == null ? 2 : m_StageNames.Length; } }
|
||||
|
||||
private SizeF BoxSize
|
||||
{
|
||||
get
|
||||
{
|
||||
float boxeswidth = TotalAreaRect.Width - NumGaps * BoxMargin;
|
||||
|
||||
float boxdim = Math.Min(TotalAreaRect.Height, boxeswidth / NumItems);
|
||||
|
||||
boxdim = Math.Max(MinBoxDimension, boxdim);
|
||||
|
||||
float oblongwidth = Math.Max(0, (boxeswidth - boxdim * NumItems) / NumItems);
|
||||
|
||||
return new SizeF(boxdim + oblongwidth, boxdim);
|
||||
}
|
||||
}
|
||||
|
||||
private RectangleF GetBoxRect(int i)
|
||||
{
|
||||
return new RectangleF(TotalAreaRect.X + i * (BoxSize.Width + BoxMargin),
|
||||
TotalAreaRect.Y + TotalAreaRect.Height / 2 - BoxSize.Height / 2,
|
||||
BoxSize.Width, BoxSize.Height);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Painting
|
||||
|
||||
GraphicsPath RoundedRect(RectangleF rect, int radius)
|
||||
{
|
||||
GraphicsPath ret = new GraphicsPath();
|
||||
|
||||
ret.StartFigure();
|
||||
|
||||
ret.AddArc(rect.X, rect.Y, 2 * radius, 2 * radius, 180, 90);
|
||||
ret.AddLine(rect.X + radius, rect.Y, rect.X + rect.Width - radius, rect.Y);
|
||||
ret.AddArc(rect.X + rect.Width - radius * 2, rect.Y, 2 * radius, 2 * radius, 270, 90);
|
||||
ret.AddLine(rect.X + rect.Width, rect.Y + radius, rect.X + rect.Width, rect.Y + rect.Height - radius);
|
||||
ret.AddArc(rect.X + rect.Width - 2*radius, rect.Y + rect.Height - 2 * radius, 2 * radius, 2 * radius, 0, 90);
|
||||
ret.AddLine(rect.X + rect.Width - radius, rect.Y + rect.Height, rect.X + radius, rect.Y + rect.Height);
|
||||
ret.AddArc(rect.X, rect.Y + rect.Height - 2*radius, 2 * radius, 2 * radius, 90, 90);
|
||||
|
||||
ret.CloseFigure();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DrawArrow(Graphics dc, Brush b, Pen p, float headsize, float y, float left, float right)
|
||||
{
|
||||
dc.DrawLine(p, new PointF(left, y), new PointF(right, y));
|
||||
|
||||
using (GraphicsPath head = new GraphicsPath())
|
||||
{
|
||||
head.StartFigure();
|
||||
|
||||
head.AddLine(new PointF(right, y), new PointF(right - headsize, y - headsize));
|
||||
head.AddLine(new PointF(right - headsize, y - headsize), new PointF(right - headsize, y + headsize));
|
||||
|
||||
head.CloseFigure();
|
||||
|
||||
dc.FillPath(b, head);
|
||||
}
|
||||
}
|
||||
|
||||
private void PipelineFlowchart_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (m_StageNames == null)
|
||||
return;
|
||||
|
||||
var dc = e.Graphics;
|
||||
|
||||
dc.CompositingQuality = CompositingQuality.HighQuality;
|
||||
dc.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
int radius = (int)Math.Min(MaxBoxCornerRadius, BoxSize.Height * BoxCornerRadiusFraction);
|
||||
|
||||
float arrowY = TotalAreaRect.Y + TotalAreaRect.Height / 2;
|
||||
|
||||
using (var pen = new Pen(Brushes.Black, BoxBorderWidth))
|
||||
using (var selectedpen = new Pen(Brushes.Red, BoxBorderWidth))
|
||||
{
|
||||
for (int i = 0; i < NumGaps; i++)
|
||||
{
|
||||
if (!m_StageFlows[i] || !m_StageFlows[i + 1])
|
||||
continue;
|
||||
|
||||
float right = TotalAreaRect.X + (i + 1) * (BoxSize.Width + BoxMargin);
|
||||
float left = right - BoxMargin;
|
||||
|
||||
DrawArrow(dc, Brushes.Black, pen, ArrowHeadSize, arrowY, left, right);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NumItems; i++)
|
||||
{
|
||||
RectangleF boxrect = GetBoxRect(i);
|
||||
|
||||
var backBrush = Brushes.Gainsboro;
|
||||
var textBrush = Brushes.Black;
|
||||
var outlinePen = pen;
|
||||
|
||||
if (!IsStageEnabled(i))
|
||||
{
|
||||
backBrush = Brushes.DarkGray;
|
||||
//textBrush = Brushes.Gainsboro;
|
||||
}
|
||||
|
||||
if (i == m_HoverStage)
|
||||
{
|
||||
backBrush = Brushes.LightYellow;
|
||||
}
|
||||
|
||||
if (i == SelectedStage)
|
||||
{
|
||||
//backBrush = Brushes.Coral;
|
||||
outlinePen = selectedpen;
|
||||
}
|
||||
|
||||
using (var boxpath = RoundedRect(boxrect, radius))
|
||||
{
|
||||
dc.FillPath(backBrush, boxpath);
|
||||
dc.DrawPath(outlinePen, boxpath);
|
||||
}
|
||||
|
||||
StringFormat format = new StringFormat();
|
||||
format.LineAlignment = StringAlignment.Center;
|
||||
format.Alignment = StringAlignment.Center;
|
||||
|
||||
var s = m_StageNames[i].Value;
|
||||
|
||||
var size = dc.MeasureString(s, Font);
|
||||
|
||||
// Decide whether we can draw the whole stage name or just the abbreviation.
|
||||
// This can look a little awkward sometimes if it's sometimes abbreviated sometimes
|
||||
// not. Maybe it should always abbreviate or not at all?
|
||||
if (size.Width + BoxLabelMargin > (float)boxrect.Width)
|
||||
{
|
||||
s = s.Replace(" ", "\n");
|
||||
size = dc.MeasureString(s, Font);
|
||||
|
||||
if (size.Width + BoxLabelMargin > (float)boxrect.Width ||
|
||||
size.Height + BoxLabelMargin > (float)boxrect.Height)
|
||||
{
|
||||
s = m_StageNames[i].Key;
|
||||
size = dc.MeasureString(s, Font);
|
||||
}
|
||||
}
|
||||
|
||||
dc.DrawString(s, Font, textBrush, new PointF(boxrect.X + boxrect.Width / 2, arrowY), format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mouse Handling
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
int old = m_HoverStage;
|
||||
m_HoverStage = -1;
|
||||
|
||||
for(int i=0; i < NumItems; i++)
|
||||
{
|
||||
if (GetBoxRect(i).Contains(e.Location))
|
||||
{
|
||||
m_HoverStage = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_HoverStage != old)
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
|
||||
m_HoverStage = -1;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnMouseClick(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseClick(e);
|
||||
|
||||
for (int i = 0; i < NumItems; i++)
|
||||
{
|
||||
if (GetBoxRect(i).Contains(e.Location))
|
||||
{
|
||||
SelectedStage = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
partial class RangeHistogram
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.whiteToolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.blackToolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// whiteToolTip
|
||||
//
|
||||
this.whiteToolTip.AutomaticDelay = 0;
|
||||
this.whiteToolTip.UseAnimation = false;
|
||||
this.whiteToolTip.UseFading = false;
|
||||
//
|
||||
// blackToolTip
|
||||
//
|
||||
this.blackToolTip.AutomaticDelay = 0;
|
||||
this.blackToolTip.UseAnimation = false;
|
||||
this.blackToolTip.UseFading = false;
|
||||
//
|
||||
// RangeHistogram
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.SystemColors.GradientActiveCaption;
|
||||
this.DoubleBuffered = true;
|
||||
this.Name = "RangeHistogram";
|
||||
this.Size = new System.Drawing.Size(150, 40);
|
||||
this.Paint += new System.Windows.Forms.PaintEventHandler(this.RangeHistogram_Paint);
|
||||
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RangeHistogram_MouseDown);
|
||||
this.MouseEnter += new System.EventHandler(this.RangeHistogram_MouseEnter);
|
||||
this.MouseLeave += new System.EventHandler(this.RangeHistogram_MouseLeave);
|
||||
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.RangeHistogram_MouseMove);
|
||||
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.RangeHistogram_MouseUp);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolTip whiteToolTip;
|
||||
private System.Windows.Forms.ToolTip blackToolTip;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,515 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
[Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
|
||||
public partial class RangeHistogram : UserControl
|
||||
{
|
||||
public RangeHistogram()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
private static readonly object RangeUpdatedEvent = new object();
|
||||
public event EventHandler<RangeHistogramEventArgs> RangeUpdated
|
||||
{
|
||||
add { Events.AddHandler(RangeUpdatedEvent, value); }
|
||||
remove { Events.RemoveHandler(RangeUpdatedEvent, value); }
|
||||
}
|
||||
protected virtual void OnRangeUpdated(RangeHistogramEventArgs e)
|
||||
{
|
||||
EventHandler<RangeHistogramEventArgs> handler = (EventHandler<RangeHistogramEventArgs>)Events[RangeUpdatedEvent];
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Privates
|
||||
|
||||
private float m_RangeMax = 1.0f;
|
||||
private float m_RangeMin = 0.0f;
|
||||
|
||||
private float m_WhitePoint = 1.0f;
|
||||
private float m_BlackPoint = 0.0f;
|
||||
|
||||
private float m_MinRangeSize = 0.001f;
|
||||
|
||||
private int m_Margin = 4;
|
||||
private int m_Border = 1;
|
||||
private int m_MarkerSize = 6;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Code Properties
|
||||
|
||||
private uint[] m_HistogramData = null;
|
||||
private float m_HistogramMin = 0.0f;
|
||||
private float m_HistogramMax = 1.0f;
|
||||
|
||||
// sets the range of data where the histogram data was calculated.
|
||||
public void SetHistogramRange(float min, float max)
|
||||
{
|
||||
m_HistogramMin = min;
|
||||
m_HistogramMax = max;
|
||||
}
|
||||
|
||||
// sets the minimum and maximum as well as the black and white points
|
||||
public void SetRange(float min, float max)
|
||||
{
|
||||
m_RangeMin = min;
|
||||
m_RangeMax = Math.Max((min+float.Epsilon)*(1.0f+m_MinRangeSize), max);
|
||||
m_BlackPoint = m_RangeMin;
|
||||
m_WhitePoint = m_RangeMax;
|
||||
|
||||
Invalidate();
|
||||
OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint));
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public uint[] HistogramData
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HistogramData;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_HistogramData = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// black point and white point are the currently selected black/white points, within the
|
||||
// minimum and maximum points. (ie. not 0 or 1)
|
||||
[Browsable(false)]
|
||||
public float BlackPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_BlackPoint;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= m_RangeMin)
|
||||
m_BlackPoint = m_RangeMin = value;
|
||||
else
|
||||
m_BlackPoint = value;
|
||||
|
||||
Invalidate();
|
||||
OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint));
|
||||
}
|
||||
}
|
||||
[Browsable(false)]
|
||||
public float WhitePoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_WhitePoint;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value >= m_RangeMax)
|
||||
m_WhitePoint = m_RangeMax = value;
|
||||
else
|
||||
m_WhitePoint = value;
|
||||
|
||||
Invalidate();
|
||||
OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint));
|
||||
}
|
||||
}
|
||||
|
||||
// range min/max are the current minimum and maximum values that can be set
|
||||
// for the black and white points
|
||||
[Browsable(false)]
|
||||
public float RangeMin
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_RangeMin;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_RangeMin = Math.Min(value, m_RangeMax - MinRangeSize);
|
||||
|
||||
Invalidate();
|
||||
OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint));
|
||||
}
|
||||
}
|
||||
[Browsable(false)]
|
||||
public float RangeMax
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_RangeMax;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_RangeMax = Math.Max(value, m_RangeMin + MinRangeSize);
|
||||
|
||||
Invalidate();
|
||||
OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Designer Properties
|
||||
|
||||
[Description("The smallest possible range that can be selected"), Category("Behavior")]
|
||||
[DefaultValue(typeof(float), "0.001")]
|
||||
public float MinRangeSize
|
||||
{
|
||||
get { return m_MinRangeSize; }
|
||||
set { m_MinRangeSize = Math.Max(0.000001f, value); }
|
||||
}
|
||||
|
||||
[Description("The margin around the range display"), Category("Layout")]
|
||||
[DefaultValue(typeof(int), "4")]
|
||||
public int RangeMargin
|
||||
{
|
||||
get { return m_Margin; }
|
||||
set { m_Margin = value; }
|
||||
}
|
||||
|
||||
[Description("The pixel border around the range bar itself"), Category("Appearance")]
|
||||
[DefaultValue(typeof(int), "1")]
|
||||
public int Border
|
||||
{
|
||||
get { return m_Border; }
|
||||
set { m_Border = value; }
|
||||
}
|
||||
|
||||
[Description("The size in pixels of each marker"), Category("Appearance")]
|
||||
[DefaultValue(typeof(int), "6")]
|
||||
public int MarkerSize
|
||||
{
|
||||
get { return m_MarkerSize; }
|
||||
set { m_MarkerSize = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Properties
|
||||
|
||||
private int m_TotalSpace { get { return m_Margin + m_Border; } }
|
||||
private int m_RegionWidth { get { return this.Width - m_TotalSpace * 2; } }
|
||||
|
||||
// these are internal only, they give [0, 1] from minimum to maximum of where the black and white points are
|
||||
private float m_BlackDelta
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDelta(BlackPoint);
|
||||
}
|
||||
set
|
||||
{
|
||||
BlackPoint = Math.Min(WhitePoint - MinRangeSize, value * (RangeMax - RangeMin) + RangeMin);
|
||||
}
|
||||
}
|
||||
private float m_WhiteDelta
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDelta(WhitePoint);
|
||||
}
|
||||
set
|
||||
{
|
||||
WhitePoint = Math.Max(BlackPoint + MinRangeSize, value * (RangeMax - RangeMin) + RangeMin);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetDelta(float val)
|
||||
{
|
||||
return (val - RangeMin) / (RangeMax - RangeMin);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tooltips
|
||||
|
||||
private void ShowTooltips()
|
||||
{
|
||||
blackToolTip.Show(BlackPoint.ToString("F4"), this,
|
||||
this.ClientRectangle.Left + (int)(this.ClientRectangle.Width * m_BlackDelta), this.ClientRectangle.Bottom);
|
||||
|
||||
whiteToolTip.Show(WhitePoint.ToString("F4"), this,
|
||||
this.ClientRectangle.Left + (int)(this.ClientRectangle.Width * m_WhiteDelta), this.ClientRectangle.Top - 15);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mouse Handlers
|
||||
|
||||
private Point m_mousePrev = new Point(-1, -1);
|
||||
|
||||
private enum DraggingMode
|
||||
{
|
||||
NONE,
|
||||
WHITE,
|
||||
BLACK,
|
||||
}
|
||||
private DraggingMode m_DragMode;
|
||||
|
||||
// This handler tries to figure out which handle (white or black) you were trying to
|
||||
// grab when you clicked.
|
||||
private void RangeHistogram_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if(e.Button != MouseButtons.Left)
|
||||
return;
|
||||
|
||||
Rectangle rect = this.ClientRectangle;
|
||||
|
||||
rect.Inflate(-m_TotalSpace, -m_TotalSpace);
|
||||
|
||||
int whiteX = (int)(m_WhiteDelta * rect.Width);
|
||||
int blackX = (int)(m_BlackDelta * rect.Width);
|
||||
|
||||
var whiteVec = new PointF(whiteX - e.Location.X, ClientRectangle.Height - e.Location.Y);
|
||||
var blackVec = new PointF(blackX-e.Location.X, e.Location.Y);
|
||||
|
||||
float whitedist = (float)Math.Sqrt(whiteVec.X * whiteVec.X + whiteVec.Y * whiteVec.Y);
|
||||
float blackdist = (float)Math.Sqrt(blackVec.X * blackVec.X + blackVec.Y * blackVec.Y);
|
||||
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("white {0} black {1}", whitedist, blackdist));
|
||||
|
||||
if (whitedist < blackdist && whitedist < 18.0f)
|
||||
m_DragMode = DraggingMode.WHITE;
|
||||
else if (blackdist < whitedist && blackdist < 18.0f)
|
||||
m_DragMode = DraggingMode.BLACK;
|
||||
else if (e.Location.X > whiteX)
|
||||
m_DragMode = DraggingMode.WHITE;
|
||||
else if (e.Location.X < blackX)
|
||||
m_DragMode = DraggingMode.BLACK;
|
||||
|
||||
if (m_DragMode == DraggingMode.WHITE)
|
||||
{
|
||||
float newWhite = (float)(e.Location.X - m_TotalSpace) / (float)m_RegionWidth;
|
||||
|
||||
m_WhiteDelta = Math.Max(m_BlackDelta + m_MinRangeSize, Math.Min(1.0f, newWhite));
|
||||
}
|
||||
else if (m_DragMode == DraggingMode.BLACK)
|
||||
{
|
||||
float newBlack = (float)(e.Location.X - m_TotalSpace) / (float)m_RegionWidth;
|
||||
|
||||
m_BlackDelta = Math.Min(m_WhiteDelta - m_MinRangeSize, Math.Max(0.0f, newBlack));
|
||||
}
|
||||
|
||||
OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint));
|
||||
|
||||
if (m_DragMode != DraggingMode.NONE)
|
||||
{
|
||||
this.Invalidate();
|
||||
this.Update();
|
||||
}
|
||||
|
||||
m_mousePrev.X = e.X;
|
||||
m_mousePrev.Y = e.Y;
|
||||
}
|
||||
|
||||
private void RangeHistogram_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
whiteToolTip.Hide(this);
|
||||
blackToolTip.Hide(this);
|
||||
|
||||
m_DragMode = DraggingMode.NONE;
|
||||
|
||||
m_mousePrev.X = m_mousePrev.Y = -1;
|
||||
}
|
||||
|
||||
private void RangeHistogram_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left && (e.X != m_mousePrev.X || e.Y != m_mousePrev.Y))
|
||||
{
|
||||
if (m_DragMode == DraggingMode.WHITE)
|
||||
{
|
||||
float newWhite = (float)(e.Location.X - m_TotalSpace) / (float)m_RegionWidth;
|
||||
|
||||
m_WhiteDelta = Math.Max(m_BlackDelta + m_MinRangeSize, Math.Min(1.0f, newWhite));
|
||||
}
|
||||
else if (m_DragMode == DraggingMode.BLACK)
|
||||
{
|
||||
float newBlack = (float)(e.Location.X - m_TotalSpace) / (float)m_RegionWidth;
|
||||
|
||||
m_BlackDelta = Math.Min(m_WhiteDelta - m_MinRangeSize, Math.Max(0.0f, newBlack));
|
||||
}
|
||||
|
||||
OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint));
|
||||
|
||||
if (m_DragMode != DraggingMode.NONE)
|
||||
{
|
||||
this.Invalidate();
|
||||
this.Update();
|
||||
}
|
||||
|
||||
m_mousePrev.X = e.X;
|
||||
m_mousePrev.Y = e.Y;
|
||||
|
||||
ShowTooltips();
|
||||
}
|
||||
}
|
||||
|
||||
private void RangeHistogram_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
whiteToolTip.Hide(this);
|
||||
blackToolTip.Hide(this);
|
||||
}
|
||||
|
||||
private void RangeHistogram_MouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
ShowTooltips();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Other Handlers
|
||||
|
||||
private void RangeHistogram_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
Rectangle rect = this.ClientRectangle;
|
||||
|
||||
e.Graphics.FillRectangle(SystemBrushes.Control, rect);
|
||||
|
||||
rect.Inflate(-m_Margin, -m_Margin);
|
||||
|
||||
e.Graphics.FillRectangle(Brushes.Black, rect);
|
||||
|
||||
rect.Inflate(-m_Border, -m_Border);
|
||||
|
||||
e.Graphics.FillRectangle(Brushes.DarkGray, rect);
|
||||
|
||||
int whiteX = (int)(m_WhiteDelta * rect.Width);
|
||||
int blackX = (int)(m_BlackDelta * rect.Width);
|
||||
|
||||
Rectangle blackPoint = new Rectangle(rect.Left, rect.Top, blackX, rect.Height);
|
||||
Rectangle whitePoint = new Rectangle(rect.Left + whiteX, rect.Top, rect.Width - whiteX, rect.Height);
|
||||
|
||||
e.Graphics.FillRectangle(Brushes.White, whitePoint);
|
||||
e.Graphics.FillRectangle(Brushes.Black, blackPoint);
|
||||
|
||||
if (HistogramData != null)
|
||||
{
|
||||
float minx = GetDelta(m_HistogramMin);
|
||||
float maxx = GetDelta(m_HistogramMax);
|
||||
|
||||
UInt32 maxval = UInt32.MinValue;
|
||||
for (int i = 0; i < HistogramData.Length; i++)
|
||||
{
|
||||
float x = (float)i / (float)HistogramData.Length;
|
||||
|
||||
float xdelta = minx + x * (maxx - minx);
|
||||
|
||||
if (xdelta >= 0.0f && xdelta <= 1.0f)
|
||||
{
|
||||
maxval = Math.Max(maxval, HistogramData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < HistogramData.Length; i++)
|
||||
{
|
||||
float x = (float)i / (float)HistogramData.Length;
|
||||
float y = (float)HistogramData[i] / (float)maxval;
|
||||
|
||||
float xdelta = minx + x * (maxx - minx);
|
||||
|
||||
if (xdelta >= 0.0f && xdelta <= 1.0f)
|
||||
{
|
||||
float segwidth = Math.Max(rect.Width * (maxx - minx) / (float)HistogramData.Length, 1);
|
||||
|
||||
RectangleF barRect = new RectangleF(new PointF(rect.Left + rect.Width * (minx + x * (maxx - minx)), rect.Bottom - rect.Height * y),
|
||||
new SizeF(segwidth, rect.Height * y));
|
||||
|
||||
e.Graphics.FillRectangle(Brushes.Green, barRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Point[] blackTriangle = { new Point(blackPoint.Right, m_MarkerSize*2),
|
||||
new Point(blackPoint.Right+m_MarkerSize, 0),
|
||||
new Point(blackPoint.Right-m_MarkerSize, 0) };
|
||||
|
||||
e.Graphics.FillPolygon(Brushes.DarkGray, blackTriangle);
|
||||
|
||||
Point[] whiteTriangle = { new Point(whitePoint.Left, whitePoint.Bottom-m_MarkerSize*2+m_Margin),
|
||||
new Point(whitePoint.Left+m_MarkerSize, whitePoint.Bottom+m_Margin),
|
||||
new Point(whitePoint.Left-m_MarkerSize, whitePoint.Bottom+m_Margin) };
|
||||
|
||||
e.Graphics.FillPolygon(Brushes.DarkGray, whiteTriangle);
|
||||
|
||||
blackTriangle[0].Y -= 2;
|
||||
blackTriangle[1].Y += 1;
|
||||
blackTriangle[2].Y += 1;
|
||||
|
||||
blackTriangle[1].X -= 2;
|
||||
blackTriangle[2].X += 2;
|
||||
|
||||
whiteTriangle[0].Y += 2;
|
||||
whiteTriangle[1].Y -= 1;
|
||||
whiteTriangle[2].Y -= 1;
|
||||
|
||||
whiteTriangle[1].X -= 2;
|
||||
whiteTriangle[2].X += 2;
|
||||
|
||||
e.Graphics.FillPolygon(Brushes.Black, blackTriangle);
|
||||
e.Graphics.FillPolygon(Brushes.White, whiteTriangle);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class RangeHistogramEventArgs : EventArgs
|
||||
{
|
||||
private float m_black, m_white;
|
||||
|
||||
public RangeHistogramEventArgs(float black, float white)
|
||||
{
|
||||
m_black = black;
|
||||
m_white = white;
|
||||
}
|
||||
|
||||
public float BlackPoint
|
||||
{
|
||||
get { return m_black; }
|
||||
}
|
||||
|
||||
public float WhitePoint
|
||||
{
|
||||
get { return m_white; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="whiteToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="blackToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>132, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
partial class ResourcePreview
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.slotLabel = new System.Windows.Forms.Label();
|
||||
this.descriptionLabel = new System.Windows.Forms.Label();
|
||||
this.thumbnail = new renderdocui.Controls.NoScrollPanel();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.BackColor = System.Drawing.Color.Transparent;
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.slotLabel, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.descriptionLabel, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.thumbnail, 0, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
|
||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(110, 86);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// slotLabel
|
||||
//
|
||||
this.slotLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.slotLabel.AutoSize = true;
|
||||
this.slotLabel.BackColor = System.Drawing.SystemColors.InactiveCaption;
|
||||
this.slotLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.slotLabel.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
|
||||
this.slotLabel.Location = new System.Drawing.Point(0, 60);
|
||||
this.slotLabel.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.slotLabel.Name = "slotLabel";
|
||||
this.slotLabel.Size = new System.Drawing.Size(19, 26);
|
||||
this.slotLabel.TabIndex = 1;
|
||||
this.slotLabel.Text = "1";
|
||||
this.slotLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.slotLabel.MouseClick += new System.Windows.Forms.MouseEventHandler(this.child_MouseClick);
|
||||
this.slotLabel.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.child_MouseDoubleClick);
|
||||
//
|
||||
// descriptionLabel
|
||||
//
|
||||
this.descriptionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.descriptionLabel.AutoEllipsis = true;
|
||||
this.descriptionLabel.BackColor = System.Drawing.SystemColors.InactiveCaption;
|
||||
this.descriptionLabel.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
|
||||
this.descriptionLabel.Location = new System.Drawing.Point(19, 60);
|
||||
this.descriptionLabel.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.descriptionLabel.Name = "descriptionLabel";
|
||||
this.descriptionLabel.Size = new System.Drawing.Size(91, 26);
|
||||
this.descriptionLabel.TabIndex = 2;
|
||||
this.descriptionLabel.Text = "Texture2D 117";
|
||||
this.descriptionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
this.descriptionLabel.MouseClick += new System.Windows.Forms.MouseEventHandler(this.child_MouseClick);
|
||||
this.descriptionLabel.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.child_MouseDoubleClick);
|
||||
//
|
||||
// thumbnail
|
||||
//
|
||||
this.thumbnail.BackColor = System.Drawing.Color.Chartreuse;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.thumbnail, 2);
|
||||
this.thumbnail.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.thumbnail.Location = new System.Drawing.Point(0, 0);
|
||||
this.thumbnail.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.thumbnail.Name = "thumbnail";
|
||||
this.thumbnail.Size = new System.Drawing.Size(110, 60);
|
||||
this.thumbnail.TabIndex = 0;
|
||||
this.thumbnail.Paint += new System.Windows.Forms.PaintEventHandler(this.thumbnail_Paint);
|
||||
this.thumbnail.MouseClick += new System.Windows.Forms.MouseEventHandler(this.child_MouseClick);
|
||||
this.thumbnail.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.child_MouseDoubleClick);
|
||||
//
|
||||
// ResourcePreview
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Margin = new System.Windows.Forms.Padding(5, 0, 0, 0);
|
||||
this.Name = "ResourcePreview";
|
||||
this.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.Size = new System.Drawing.Size(116, 92);
|
||||
this.Load += new System.EventHandler(this.ResourcePreview_Load);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private Controls.NoScrollPanel thumbnail;
|
||||
private System.Windows.Forms.Label slotLabel;
|
||||
private System.Windows.Forms.Label descriptionLabel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using renderdocui.Code;
|
||||
using renderdoc;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
[Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
|
||||
public partial class ResourcePreview : UserControl
|
||||
{
|
||||
private string m_Name;
|
||||
private UInt32 m_Width, m_Height, m_Depth, m_NumMips;
|
||||
private Core m_Core;
|
||||
private ReplayOutput m_Output;
|
||||
private IntPtr m_Handle;
|
||||
|
||||
public ResourcePreview(Core core, ReplayOutput output)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
m_Name = "Unbound";
|
||||
m_Width = 1;
|
||||
m_Height = 1;
|
||||
m_Depth = 1;
|
||||
m_NumMips = 0;
|
||||
m_Unbound = true;
|
||||
thumbnail.Painting = false;
|
||||
|
||||
m_Unbound = true;
|
||||
|
||||
slotLabel.Text = "0";
|
||||
|
||||
this.DoubleBuffered = true;
|
||||
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
|
||||
|
||||
m_Handle = thumbnail.Handle;
|
||||
|
||||
m_Core = core;
|
||||
m_Output = output;
|
||||
|
||||
Selected = false;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
descriptionLabel.Text = "Unbound";
|
||||
m_Unbound = true;
|
||||
thumbnail.Painting = true;
|
||||
}
|
||||
|
||||
public void Init(string Name, UInt32 Width, UInt32 Height, UInt32 Depth, UInt32 NumMips)
|
||||
{
|
||||
m_Name = Name;
|
||||
m_Width = Width;
|
||||
m_Height = Height;
|
||||
m_Depth = Depth;
|
||||
m_NumMips = NumMips;
|
||||
m_Unbound = false;
|
||||
thumbnail.Painting = true;
|
||||
|
||||
//descriptionLabel.Text = m_Width + "x" + m_Height + "x" + m_Depth + (m_NumMips > 0 ? "[" + m_NumMips + "]\n" : "\n") + m_Name;
|
||||
descriptionLabel.Text = m_Name;
|
||||
}
|
||||
|
||||
public string SlotName
|
||||
{
|
||||
get { return slotLabel.Text; }
|
||||
set { slotLabel.Text = value; }
|
||||
}
|
||||
|
||||
private bool m_Unbound = true;
|
||||
public bool Unbound
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Unbound;
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_Selected;
|
||||
public bool Selected
|
||||
{
|
||||
get { return m_Selected; }
|
||||
set
|
||||
{
|
||||
m_Selected = value;
|
||||
if (value)
|
||||
{
|
||||
BackColor = Color.Red;
|
||||
}
|
||||
else
|
||||
{
|
||||
BackColor = Color.Black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IntPtr ThumbnailHandle
|
||||
{
|
||||
get { return m_Handle; }
|
||||
}
|
||||
|
||||
private void ResourcePreview_Load(object sender, EventArgs e)
|
||||
{
|
||||
Init(m_Name, m_Width, m_Height, m_Depth, m_NumMips);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
thumbnail.Invalidate();
|
||||
}
|
||||
|
||||
private void thumbnail_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (m_Output == null || m_Core.Renderer == null)
|
||||
{
|
||||
e.Graphics.Clear(Color.Black);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Output != null)
|
||||
m_Core.Renderer.Invoke((ReplayRenderer r) => { m_Output.Display(); });
|
||||
}
|
||||
|
||||
public void SetSize(Size s)
|
||||
{
|
||||
MinimumSize = MaximumSize = s;
|
||||
Size = s;
|
||||
}
|
||||
|
||||
private void child_MouseClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
OnMouseClick(e);
|
||||
}
|
||||
|
||||
private void child_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
OnMouseDoubleClick(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using renderdocui.Code;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
// thanks to Hans Passant - http://stackoverflow.com/a/6954785
|
||||
public class TablessControl : TabControl
|
||||
{
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
// Hide tabs by trapping the TCM_ADJUSTRECT message
|
||||
if (m.Msg == (int)Win32PInvoke.Win32Message.TCM_ADJUSTRECT && !DesignMode)
|
||||
m.Result = (IntPtr)1;
|
||||
else
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using renderdoc;
|
||||
using renderdocui.Code;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
public partial class TextureListBox : ListBox
|
||||
{
|
||||
private List<FetchTexture> m_FilteredTextures = new List<FetchTexture>();
|
||||
|
||||
private static readonly object GoIconClickEvent = new object();
|
||||
public event EventHandler<GoIconClickEventArgs> GoIconClick
|
||||
{
|
||||
add { Events.AddHandler(GoIconClickEvent, value); }
|
||||
remove { Events.RemoveHandler(GoIconClickEvent, value); }
|
||||
}
|
||||
protected virtual void OnGoIconClick(GoIconClickEventArgs e)
|
||||
{
|
||||
EventHandler<GoIconClickEventArgs> handler = (EventHandler<GoIconClickEventArgs>)Events[GoIconClickEvent];
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public Core m_Core = null;
|
||||
|
||||
public TextureListBox()
|
||||
{
|
||||
DrawMode = DrawMode.OwnerDrawFixed;
|
||||
DrawItem += new DrawItemEventHandler(TextureListBox_DrawItem);
|
||||
|
||||
this.DoubleBuffered = true;
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
|
||||
|
||||
Items.Clear();
|
||||
Items.Add("foobar");
|
||||
}
|
||||
|
||||
void TextureListBox_DrawItem(object sender, DrawItemEventArgs e)
|
||||
{
|
||||
if (Items.Count > 0 && e.Index >= 0)
|
||||
{
|
||||
Rectangle stringBounds = e.Bounds;
|
||||
|
||||
var image = global::renderdocui.Properties.Resources.action;
|
||||
|
||||
if (m_HoverHighlight == e.Index)
|
||||
{
|
||||
image = global::renderdocui.Properties.Resources.action_hover;
|
||||
e.Graphics.DrawRectangle(Pens.LightGray, e.Bounds);
|
||||
}
|
||||
|
||||
e.Graphics.DrawImage(image, e.Bounds.Width - 16, e.Bounds.Y, 16, 16);
|
||||
|
||||
stringBounds.Width -= 18;
|
||||
|
||||
var sf = new StringFormat(StringFormat.GenericDefault);
|
||||
|
||||
sf.Trimming = StringTrimming.EllipsisCharacter;
|
||||
sf.FormatFlags |= StringFormatFlags.NoWrap;
|
||||
|
||||
using (Brush b = new SolidBrush(ForeColor))
|
||||
{
|
||||
e.Graphics.DrawString(Items[e.Index].ToString(),
|
||||
Font, b, stringBounds, sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int m_HoverHighlight = -1;
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseClick(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseClick(e);
|
||||
|
||||
if (Items.Count > 0 && m_HoverHighlight >= 0)
|
||||
{
|
||||
var rect = GetItemRectangle(m_HoverHighlight);
|
||||
|
||||
if (rect.Contains(e.Location))
|
||||
{
|
||||
OnGoIconClick(new GoIconClickEventArgs(m_FilteredTextures[m_HoverHighlight].ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
bool curhover = m_HoverHighlight != -1;
|
||||
bool hover = false;
|
||||
|
||||
for(int i=0; i < Items.Count; i++)
|
||||
{
|
||||
var rect = GetItemRectangle(i);
|
||||
|
||||
bool highlight = rect.Contains(e.Location);
|
||||
|
||||
hover |= highlight;
|
||||
|
||||
if (m_HoverHighlight != i && highlight)
|
||||
{
|
||||
m_HoverHighlight = i;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
if (hover)
|
||||
{
|
||||
Cursor = Cursors.Hand;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor = Cursors.Arrow;
|
||||
m_HoverHighlight = -1;
|
||||
}
|
||||
|
||||
if (hover != curhover)
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
|
||||
Cursor = Cursors.Arrow;
|
||||
if (Items.Count > 0 && m_HoverHighlight >= 0)
|
||||
Invalidate(GetItemRectangle(m_HoverHighlight));
|
||||
|
||||
m_HoverHighlight = -1;
|
||||
}
|
||||
|
||||
protected override void OnVisibleChanged(EventArgs e)
|
||||
{
|
||||
base.OnVisibleChanged(e);
|
||||
|
||||
if (Visible)
|
||||
{
|
||||
FillTextureList("", true, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
|
||||
for (int i = 0; i < Items.Count; i++)
|
||||
{
|
||||
TextureListBox_DrawItem(this, new DrawItemEventArgs(e.Graphics, Font, GetItemRectangle(i), i, DrawItemState.Default));
|
||||
}
|
||||
}
|
||||
|
||||
public void FillTextureList(string filter, bool RTs, bool Texs)
|
||||
{
|
||||
m_FilteredTextures.Clear();
|
||||
Items.Clear();
|
||||
|
||||
if (m_Core == null ||!m_Core.LogLoaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_Core.CurTextures.Length; i++)
|
||||
{
|
||||
bool include = false;
|
||||
include |= (RTs && ((m_Core.CurTextures[i].creationFlags & TextureCreationFlags.RTV) > 0 ||
|
||||
(m_Core.CurTextures[i].creationFlags & TextureCreationFlags.DSV) > 0));
|
||||
include |= (Texs && (m_Core.CurTextures[i].creationFlags & TextureCreationFlags.RTV) == 0 &&
|
||||
(m_Core.CurTextures[i].creationFlags & TextureCreationFlags.DSV) == 0);
|
||||
include |= (filter != "" && (m_Core.CurTextures[i].name.ToLowerInvariant().Contains(filter.ToLowerInvariant())));
|
||||
include |= (!RTs && !Texs && filter == "");
|
||||
|
||||
if (include)
|
||||
{
|
||||
m_FilteredTextures.Add(m_Core.CurTextures[i]);
|
||||
Items.Add(m_Core.CurTextures[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GoIconClickEventArgs : EventArgs
|
||||
{
|
||||
private ResourceId id;
|
||||
|
||||
public GoIconClickEventArgs(ResourceId i)
|
||||
{
|
||||
id = i;
|
||||
}
|
||||
|
||||
public ResourceId ID
|
||||
{
|
||||
get { return id; }
|
||||
}
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
partial class ThumbnailStrip
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
this.panel = new System.Windows.Forms.Panel();
|
||||
this.hscroll = new System.Windows.Forms.HScrollBar();
|
||||
this.vscroll = new System.Windows.Forms.VScrollBar();
|
||||
tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.ColumnCount = 2;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
tableLayoutPanel1.Controls.Add(this.panel, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(this.hscroll, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(this.vscroll, 1, 0);
|
||||
tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 2;
|
||||
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
tableLayoutPanel1.Size = new System.Drawing.Size(791, 246);
|
||||
tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// panel
|
||||
//
|
||||
this.panel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panel.Name = "panel";
|
||||
this.panel.Size = new System.Drawing.Size(775, 230);
|
||||
this.panel.TabIndex = 0;
|
||||
this.panel.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.panel_ControlAddRemove);
|
||||
this.panel.ControlRemoved += new System.Windows.Forms.ControlEventHandler(this.panel_ControlAddRemove);
|
||||
this.panel.MouseClick += new System.Windows.Forms.MouseEventHandler(this.panel_MouseClick);
|
||||
//
|
||||
// hscroll
|
||||
//
|
||||
this.hscroll.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.hscroll.Location = new System.Drawing.Point(0, 230);
|
||||
this.hscroll.Name = "hscroll";
|
||||
this.hscroll.Size = new System.Drawing.Size(775, 16);
|
||||
this.hscroll.TabIndex = 1;
|
||||
this.hscroll.Scroll += new System.Windows.Forms.ScrollEventHandler(this.hscroll_Scroll);
|
||||
//
|
||||
// vscroll
|
||||
//
|
||||
this.vscroll.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this.vscroll.Location = new System.Drawing.Point(775, 0);
|
||||
this.vscroll.Name = "vscroll";
|
||||
this.vscroll.Size = new System.Drawing.Size(16, 230);
|
||||
this.vscroll.TabIndex = 2;
|
||||
this.vscroll.Scroll += new System.Windows.Forms.ScrollEventHandler(this.vscroll_Scroll);
|
||||
//
|
||||
// ThumbnailStrip
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(tableLayoutPanel1);
|
||||
this.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.Name = "ThumbnailStrip";
|
||||
this.Size = new System.Drawing.Size(791, 246);
|
||||
this.Layout += new System.Windows.Forms.LayoutEventHandler(this.ThumbnailStrip_Layout);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panel;
|
||||
private System.Windows.Forms.HScrollBar hscroll;
|
||||
private System.Windows.Forms.VScrollBar vscroll;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
public partial class ThumbnailStrip : UserControl
|
||||
{
|
||||
public ThumbnailStrip()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
MouseWheel += new MouseEventHandler(ThumbnailStrip_MouseWheel);
|
||||
}
|
||||
|
||||
void ThumbnailStrip_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
const int WHEEL_DELTA = 120;
|
||||
|
||||
int movement = e.Delta / WHEEL_DELTA;
|
||||
|
||||
if (vscroll.Visible)
|
||||
vscroll.Value = Code.Helpers.Clamp(vscroll.Value - movement * vscroll.SmallChange, vscroll.Minimum, vscroll.Maximum - vscroll.LargeChange);
|
||||
if (hscroll.Visible)
|
||||
hscroll.Value = Code.Helpers.Clamp(hscroll.Value - movement * hscroll.SmallChange, hscroll.Minimum, hscroll.Maximum - hscroll.LargeChange);
|
||||
|
||||
RefreshLayout();
|
||||
}
|
||||
|
||||
private List<ResourcePreview> m_Thumbnails = new List<ResourcePreview>();
|
||||
public ResourcePreview[] Thumbnails { get { return m_Thumbnails.ToArray(); } }
|
||||
|
||||
public void AddThumbnail(ResourcePreview r)
|
||||
{
|
||||
panel.Controls.Add(r);
|
||||
m_Thumbnails.Add(r);
|
||||
}
|
||||
|
||||
public void ClearThumbnails()
|
||||
{
|
||||
m_Thumbnails.Clear();
|
||||
panel.Controls.Clear();
|
||||
}
|
||||
|
||||
public void RefreshLayout()
|
||||
{
|
||||
Rectangle avail = ClientRectangle;
|
||||
avail.Inflate(new Size(-6, -6));
|
||||
|
||||
int numVisible = 0;
|
||||
foreach (ResourcePreview c in Thumbnails)
|
||||
if (c.Visible) numVisible++;
|
||||
|
||||
// depending on overall aspect ratio, we either lay out the strip horizontally or
|
||||
// vertically. This tries to account for whether the strip is docked along one side
|
||||
// or another of the texture viewer
|
||||
if (avail.Width > avail.Height)
|
||||
{
|
||||
avail.Width += 6; // controls implicitly have a 6 margin on the right
|
||||
|
||||
int aspectWidth = (int)(avail.Height * 1.3f);
|
||||
|
||||
vscroll.Visible = false;
|
||||
|
||||
int noscrollWidth = numVisible * (aspectWidth + 6);
|
||||
|
||||
if (noscrollWidth <= avail.Width)
|
||||
{
|
||||
hscroll.Visible = false;
|
||||
|
||||
int x = avail.X;
|
||||
foreach (ResourcePreview c in Thumbnails)
|
||||
{
|
||||
if (c.Visible)
|
||||
{
|
||||
c.Location = new Point(x, avail.Y);
|
||||
c.SetSize(new Size(aspectWidth, avail.Height));
|
||||
|
||||
x += aspectWidth + 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hscroll.Visible = true;
|
||||
|
||||
avail.Height = avail.Height - SystemInformation.HorizontalScrollBarHeight;
|
||||
|
||||
aspectWidth = (int)(avail.Height * 1.3f);
|
||||
|
||||
int totalWidth = numVisible * (aspectWidth + 6);
|
||||
hscroll.Enabled = totalWidth > avail.Width;
|
||||
|
||||
if (hscroll.Enabled)
|
||||
{
|
||||
hscroll.Maximum = totalWidth - avail.Width;
|
||||
hscroll.LargeChange = Code.Helpers.Clamp(avail.Height, 1, hscroll.Maximum/2);
|
||||
hscroll.SmallChange = Math.Max(1, hscroll.LargeChange / 2);
|
||||
}
|
||||
|
||||
int x = avail.X - (int)(hscroll.Maximum*(float)hscroll.Value/(float)(hscroll.Maximum-hscroll.LargeChange));
|
||||
foreach (ResourcePreview c in Thumbnails)
|
||||
{
|
||||
if (c.Visible)
|
||||
{
|
||||
c.Location = new Point(x, avail.Y);
|
||||
c.SetSize(new Size(aspectWidth, avail.Height));
|
||||
|
||||
x += aspectWidth + 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
avail.Height += 6; // controls implicitly have a 6 margin on the bottom
|
||||
|
||||
int aspectHeight = (int)(avail.Width / 1.3f);
|
||||
|
||||
hscroll.Visible = false;
|
||||
|
||||
int noscrollHeight = numVisible * (aspectHeight + 6);
|
||||
|
||||
if (noscrollHeight <= avail.Height)
|
||||
{
|
||||
vscroll.Visible = false;
|
||||
|
||||
int y = avail.Y;
|
||||
foreach (ResourcePreview c in Thumbnails)
|
||||
{
|
||||
if (c.Visible)
|
||||
{
|
||||
c.Location = new Point(avail.X, y);
|
||||
c.SetSize(new Size(avail.Width, aspectHeight));
|
||||
|
||||
y += aspectHeight + 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vscroll.Visible = true;
|
||||
|
||||
avail.Width = avail.Width - SystemInformation.VerticalScrollBarWidth;
|
||||
|
||||
aspectHeight = (int)(avail.Width / 1.3f);
|
||||
|
||||
int totalHeight = numVisible * (aspectHeight + 6);
|
||||
vscroll.Enabled = totalHeight > avail.Height;
|
||||
|
||||
if (vscroll.Enabled)
|
||||
{
|
||||
vscroll.Maximum = totalHeight - avail.Height;
|
||||
vscroll.LargeChange = Code.Helpers.Clamp(avail.Width, 1, vscroll.Maximum / 2);
|
||||
vscroll.SmallChange = Math.Max(1, vscroll.LargeChange / 2);
|
||||
}
|
||||
|
||||
int y = avail.Y - (int)(vscroll.Maximum * (float)vscroll.Value / (float)(vscroll.Maximum - vscroll.LargeChange));
|
||||
foreach (ResourcePreview c in Thumbnails)
|
||||
{
|
||||
if (c.Visible)
|
||||
{
|
||||
c.Location = new Point(avail.X, y);
|
||||
c.SetSize(new Size(avail.Width, aspectHeight));
|
||||
|
||||
y += aspectHeight + 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ThumbnailStrip_Layout(object sender, LayoutEventArgs e)
|
||||
{
|
||||
RefreshLayout();
|
||||
}
|
||||
|
||||
private void panel_ControlAddRemove(object sender, ControlEventArgs e)
|
||||
{
|
||||
RefreshLayout();
|
||||
}
|
||||
|
||||
private void panel_MouseClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
OnMouseClick(e);
|
||||
}
|
||||
|
||||
private void hscroll_Scroll(object sender, ScrollEventArgs e)
|
||||
{
|
||||
RefreshLayout();
|
||||
}
|
||||
|
||||
private void vscroll_Scroll(object sender, ScrollEventArgs e)
|
||||
{
|
||||
RefreshLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="tableLayoutPanel1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,109 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace renderdocui.Controls
|
||||
{
|
||||
// toolstrip textbox that resizes to fit
|
||||
// http://msdn.microsoft.com/en-us/library/ms404304(v=vs.90).aspx
|
||||
public class ToolStripSpringTextBox : ToolStripTextBox
|
||||
{
|
||||
public override Size GetPreferredSize(Size constrainingSize)
|
||||
{
|
||||
// Use the default size if the text box is on the overflow menu
|
||||
// or is on a vertical ToolStrip.
|
||||
if (IsOnOverflow || Owner.Orientation == Orientation.Vertical)
|
||||
{
|
||||
return DefaultSize;
|
||||
}
|
||||
|
||||
// Declare a variable to store the total available width as
|
||||
// it is calculated, starting with the display width of the
|
||||
// owning ToolStrip.
|
||||
Int32 width = Owner.DisplayRectangle.Width;
|
||||
|
||||
// Subtract the width of the overflow button if it is displayed.
|
||||
if (Owner.OverflowButton.Visible)
|
||||
{
|
||||
width = width - Owner.OverflowButton.Width -
|
||||
Owner.OverflowButton.Margin.Horizontal;
|
||||
}
|
||||
|
||||
// Declare a variable to maintain a count of ToolStripSpringTextBox
|
||||
// items currently displayed in the owning ToolStrip.
|
||||
Int32 springBoxCount = 0;
|
||||
|
||||
foreach (ToolStripItem item in Owner.Items)
|
||||
{
|
||||
// Ignore items on the overflow menu.
|
||||
if (item.IsOnOverflow) continue;
|
||||
|
||||
if (item is ToolStripSpringTextBox)
|
||||
{
|
||||
// For ToolStripSpringTextBox items, increment the count and
|
||||
// subtract the margin width from the total available width.
|
||||
springBoxCount++;
|
||||
width -= item.Margin.Horizontal;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For all other items, subtract the full width from the total
|
||||
// available width.
|
||||
width = width - item.Width - item.Margin.Horizontal;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are multiple ToolStripSpringTextBox items in the owning
|
||||
// ToolStrip, divide the total available width between them.
|
||||
if (springBoxCount > 1) width /= springBoxCount;
|
||||
|
||||
// If the available width is less than the default width, use the
|
||||
// default width, forcing one or more items onto the overflow menu.
|
||||
if (width < DefaultSize.Width) width = DefaultSize.Width;
|
||||
|
||||
// Retrieve the preferred size from the base class, but change the
|
||||
// width to the calculated width.
|
||||
Size size = base.GetPreferredSize(constrainingSize);
|
||||
size.Width = width;
|
||||
return size;
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
|
||||
{
|
||||
if (keyData == Keys.Escape)
|
||||
{
|
||||
OnKeyPress(new KeyPressEventArgs('\0'));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>The Code Project Open License (CPOL)</title>
|
||||
<Style>
|
||||
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
|
||||
H1,H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
|
||||
H1 { font-size: 14pt;color:black }
|
||||
H2 { font-size: 13pt; }
|
||||
H3 { font-size: 12pt; }
|
||||
H4 { font-size: 10pt; color: black; }
|
||||
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
|
||||
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
|
||||
.SpacedList li { padding: 5px 0px 5px 0px;}
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF" color=#000000>
|
||||
|
||||
<h1>The Code Project Open License (CPOL) 1.02</h1>
|
||||
<br />
|
||||
|
||||
<center>
|
||||
<div style="text-align: left; border: 2px solid #000000; width: 660; background-color: #FFFFD9; padding: 20px;">
|
||||
|
||||
<h2>Preamble</h2>
|
||||
<p>
|
||||
This License governs Your use of the Work. This License is intended to allow developers
|
||||
to use the Source Code and Executable Files provided as part of the Work in any
|
||||
application in any form.
|
||||
</p>
|
||||
<p>
|
||||
The main points subject to the terms of the License are:</p>
|
||||
<ul>
|
||||
<li>Source Code and Executable Files can be used in commercial applications;</li>
|
||||
<li>Source Code and Executable Files can be redistributed; and</li>
|
||||
<li>Source Code can be modified to create derivative works.</li>
|
||||
<li>No claim of suitability, guarantee, or any warranty whatsoever is provided. The software is
|
||||
provided "as-is".</li>
|
||||
<li>The Article accompanying the Work may not be distributed or republished without the
|
||||
Author's consent</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This License is entered between You, the individual or other entity reading or otherwise
|
||||
making use of the Work licensed pursuant to this License and the individual or other
|
||||
entity which offers the Work under the terms of this License ("Author").</p>
|
||||
|
||||
<h2>License</h2>
|
||||
<p>
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CODE PROJECT OPEN
|
||||
LICENSE ("LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE
|
||||
LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT
|
||||
LAW IS PROHIBITED.</p>
|
||||
<p>
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HEREIN, YOU ACCEPT AND AGREE TO BE
|
||||
BOUND BY THE TERMS OF THIS LICENSE. THE AUTHOR GRANTS YOU THE RIGHTS CONTAINED HEREIN
|
||||
IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. IF YOU DO NOT
|
||||
AGREE TO ACCEPT AND BE BOUND BY THE TERMS OF THIS LICENSE, YOU CANNOT MAKE ANY
|
||||
USE OF THE WORK.</p>
|
||||
|
||||
<ol class="SpacedList">
|
||||
<li><strong>Definitions.</strong>
|
||||
|
||||
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
||||
<li><strong>"Articles"</strong> means, collectively, all articles written by Author
|
||||
which describes how the Source Code and Executable Files for the Work may be used
|
||||
by a user.</li>
|
||||
<li><b>"Author"</b> means the individual or entity that offers the Work under the terms
|
||||
of this License.<strong></strong></li>
|
||||
<li><strong>"Derivative Work"</strong> means a work based upon the Work or upon the
|
||||
Work and other pre-existing works.</li>
|
||||
<li><b>"Executable Files"</b> refer to the executables, binary files, configuration
|
||||
and any required data files included in the Work.</li>
|
||||
<li>"<b>Publisher</b>" means the provider of the website, magazine, CD-ROM, DVD or other
|
||||
medium from or by which the Work is obtained by You.</li>
|
||||
<li><b>"Source Code"</b> refers to the collection of source code and configuration files
|
||||
used to create the Executable Files.</li>
|
||||
<li><b>"Standard Version"</b> refers to such a Work if it has not been modified, or
|
||||
has been modified in accordance with the consent of the Author, such consent being
|
||||
in the full discretion of the Author. </li>
|
||||
<li><b>"Work"</b> refers to the collection of files distributed by the Publisher, including
|
||||
the Source Code, Executable Files, binaries, data files, documentation, whitepapers
|
||||
and the Articles. </li>
|
||||
<li><b>"You"</b> is you, an individual or entity wishing to use the Work and exercise
|
||||
your rights under this License.
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
|
||||
<li><strong>Fair Use/Fair Use Rights.</strong> Nothing in this License is intended to
|
||||
reduce, limit, or restrict any rights arising from fair use, fair dealing, first
|
||||
sale or other limitations on the exclusive rights of the copyright owner under copyright
|
||||
law or other applicable laws.
|
||||
</li>
|
||||
|
||||
<li><strong>License Grant.</strong> Subject to the terms and conditions of this License,
|
||||
the Author hereby grants You a worldwide, royalty-free, non-exclusive, perpetual
|
||||
(for the duration of the applicable copyright) license to exercise the rights in
|
||||
the Work as stated below:
|
||||
|
||||
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
||||
<li>You may use the standard version of the Source Code or Executable Files in Your
|
||||
own applications. </li>
|
||||
<li>You may apply bug fixes, portability fixes and other modifications obtained from
|
||||
the Public Domain or from the Author. A Work modified in such a way shall still
|
||||
be considered the standard version and will be subject to this License.</li>
|
||||
<li>You may otherwise modify Your copy of this Work (excluding the Articles) in any
|
||||
way to create a Derivative Work, provided that You insert a prominent notice in
|
||||
each changed file stating how, when and where You changed that file.</li>
|
||||
<li>You may distribute the standard version of the Executable Files and Source Code
|
||||
or Derivative Work in aggregate with other (possibly commercial) programs as part
|
||||
of a larger (possibly commercial) software distribution. </li>
|
||||
<li>The Articles discussing the Work published in any form by the author may not be
|
||||
distributed or republished without the Author's consent. The author retains
|
||||
copyright to any such Articles. You may use the Executable Files and Source Code
|
||||
pursuant to this License but you may not repost or republish or otherwise distribute
|
||||
or make available the Articles, without the prior written consent of the Author.</li>
|
||||
</ol>
|
||||
|
||||
Any subroutines or modules supplied by You and linked into the Source Code or Executable
|
||||
Files of this Work shall not be considered part of this Work and will not be subject
|
||||
to the terms of this License.
|
||||
</li>
|
||||
|
||||
<li><strong>Patent License.</strong> Subject to the terms and conditions of this License,
|
||||
each Author hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have made, use, import,
|
||||
and otherwise transfer the Work.</li>
|
||||
|
||||
<li><strong>Restrictions.</strong> The license granted in Section 3 above is expressly
|
||||
made subject to and limited by the following restrictions:
|
||||
|
||||
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
||||
<li>You agree not to remove any of the original copyright, patent, trademark, and
|
||||
attribution notices and associated disclaimers that may appear in the Source Code
|
||||
or Executable Files. </li>
|
||||
<li>You agree not to advertise or in any way imply that this Work is a product of Your
|
||||
own. </li>
|
||||
<li>The name of the Author may not be used to endorse or promote products derived from
|
||||
the Work without the prior written consent of the Author.</li>
|
||||
<li>You agree not to sell, lease, or rent any part of the Work. This does not restrict
|
||||
you from including the Work or any part of the Work inside a larger software
|
||||
distribution that itself is being sold. The Work by itself, though, cannot be sold,
|
||||
leased or rented.</li>
|
||||
<li>You may distribute the Executable Files and Source Code only under the terms of
|
||||
this License, and You must include a copy of, or the Uniform Resource Identifier
|
||||
for, this License with every copy of the Executable Files or Source Code You distribute
|
||||
and ensure that anyone receiving such Executable Files and Source Code agrees that
|
||||
the terms of this License apply to such Executable Files and/or Source Code. You
|
||||
may not offer or impose any terms on the Work that alter or restrict the terms of
|
||||
this License or the recipients' exercise of the rights granted hereunder. You
|
||||
may not sublicense the Work. You must keep intact all notices that refer to this
|
||||
License and to the disclaimer of warranties. You may not distribute the Executable
|
||||
Files or Source Code with any technological measures that control access or use
|
||||
of the Work in a manner inconsistent with the terms of this License. </li>
|
||||
<li>You agree not to use the Work for illegal, immoral or improper purposes, or on pages
|
||||
containing illegal, immoral or improper material. The Work is subject to applicable
|
||||
export laws. You agree to comply with all such laws and regulations that may apply
|
||||
to the Work after Your receipt of the Work.
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
|
||||
<li><strong>Representations, Warranties and Disclaimer.</strong> THIS WORK IS PROVIDED
|
||||
"AS IS", "WHERE IS" AND "AS AVAILABLE", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES
|
||||
OR CONDITIONS OR GUARANTEES. YOU, THE USER, ASSUME ALL RISK IN ITS USE, INCLUDING
|
||||
COPYRIGHT INFRINGEMENT, PATENT INFRINGEMENT, SUITABILITY, ETC. AUTHOR EXPRESSLY
|
||||
DISCLAIMS ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS, INCLUDING
|
||||
WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY
|
||||
OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT,
|
||||
OR THAT THE WORK (OR ANY PORTION THEREOF) IS CORRECT, USEFUL, BUG-FREE OR FREE OF
|
||||
VIRUSES. YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE
|
||||
WORKS.
|
||||
</li>
|
||||
|
||||
<li><b>Indemnity. </b>You agree to defend, indemnify and hold harmless the Author and
|
||||
the Publisher from and against any claims, suits, losses, damages, liabilities,
|
||||
costs, and expenses (including reasonable legal or attorneys’ fees) resulting from
|
||||
or relating to any use of the Work by You.
|
||||
</li>
|
||||
|
||||
<li><strong>Limitation on Liability.</strong> EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
|
||||
LAW, IN NO EVENT WILL THE AUTHOR OR THE PUBLISHER BE LIABLE TO YOU ON ANY LEGAL
|
||||
THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
|
||||
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK OR OTHERWISE, EVEN IF THE AUTHOR
|
||||
OR THE PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
</li>
|
||||
|
||||
<li><strong>Termination.</strong>
|
||||
|
||||
<ol style="list-style-type: lower-alpha;">
|
||||
<li>This License and the rights granted hereunder will terminate automatically upon
|
||||
any breach by You of any term of this License. Individuals or entities who have
|
||||
received Derivative Works from You under this License, however, will not have their
|
||||
licenses terminated provided such individuals or entities remain in full compliance
|
||||
with those licenses. Sections 1, 2, 6, 7, 8, 9, 10 and 11 will survive any termination
|
||||
of this License. </li>
|
||||
|
||||
<li>If You bring a copyright, trademark, patent or any other infringement claim against
|
||||
any contributor over infringements You claim are made by the Work, your License
|
||||
from such contributor to the Work ends automatically.</li>
|
||||
|
||||
<li>Subject to the above terms and conditions, this License is perpetual (for the duration
|
||||
of the applicable copyright in the Work). Notwithstanding the above, the Author
|
||||
reserves the right to release the Work under different license terms or to stop
|
||||
distributing the Work at any time; provided, however that any such election will
|
||||
not serve to withdraw this License (or any other license that has been, or is required
|
||||
to be, granted under the terms of this License), and this License will continue
|
||||
in full force and effect unless terminated as stated above.
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
|
||||
<li><strong>Publisher</strong>. The parties hereby confirm that the Publisher shall
|
||||
not, under any circumstances, be responsible for and shall not have any liability
|
||||
in respect of the subject matter of this License. The Publisher makes no warranty
|
||||
whatsoever in connection with the Work and shall not be liable to You or any party
|
||||
on any legal theory for any damages whatsoever, including without limitation any
|
||||
general, special, incidental or consequential damages arising in connection to this
|
||||
license. The Publisher reserves the right to cease making the Work available to
|
||||
You at any time without notice</li>
|
||||
|
||||
<li><strong>Miscellaneous</strong>
|
||||
|
||||
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
||||
<li>This License shall be governed by the laws of the location of the head office of
|
||||
the Author or if the Author is an individual, the laws of location of the principal
|
||||
place of residence of the Author.</li>
|
||||
<li>If any provision of this License is invalid or unenforceable under applicable law,
|
||||
it shall not affect the validity or enforceability of the remainder of the terms
|
||||
of this License, and without further action by the parties to this License, such
|
||||
provision shall be reformed to the minimum extent necessary to make such provision
|
||||
valid and enforceable. </li>
|
||||
<li>No term or provision of this License shall be deemed waived and no breach consented
|
||||
to unless such waiver or consent shall be in writing and signed by the party to
|
||||
be charged with such waiver or consent. </li>
|
||||
<li>This License constitutes the entire agreement between the parties with respect to
|
||||
the Work licensed herein. There are no understandings, agreements or representations
|
||||
with respect to the Work not specified herein. The Author shall not be bound by
|
||||
any additional provisions that may appear in any communication from You. This License
|
||||
may not be modified without the mutual written agreement of the Author and You.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
</center>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
This control is almost entirely taken from http://www.codeproject.com/Articles/23746/TreeView-with-Columns by jkristia.
|
||||
|
||||
Minor changes have been made to clean up, rename or reorganise - as well as a few fixes to the non-visual styles rendering path
|
||||
and some additional changes for my use of the control (like having the tree controls in a column other than the first, which mostly
|
||||
'Just Worked' (tm) ).
|
||||
|
||||
So all credit goes to the above author!
|
||||
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.Design;
|
||||
|
||||
// Taken from http://www.codeproject.com/Articles/23746/TreeView-with-Columns with minor tweaks
|
||||
// and fixes for my purposes.
|
||||
namespace TreelistView
|
||||
{
|
||||
// http://msdn2.microsoft.com/en-us/library/9zky1t4k.aspx
|
||||
|
||||
// Extending Design-Time Support
|
||||
// ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxdeveloping/html/d6ac8a6a-42fd-4bc8-bf33-b212811297e2.htm
|
||||
// http://msdn2.microsoft.com/en-us/library/37899azc.aspx
|
||||
|
||||
// description of the property grid
|
||||
// http://msdn2.microsoft.com/en-us/library/aa302326.aspx
|
||||
// http://msdn2.microsoft.com/en-us/library/aa302334.aspx
|
||||
|
||||
// another good one explaining
|
||||
// http://www.codeproject.com/KB/cs/dzcollectioneditor.aspx?print=true
|
||||
public class ColumnCollectionEditor : CollectionEditor
|
||||
{
|
||||
public ColumnCollectionEditor(Type type) : base(type)
|
||||
{
|
||||
}
|
||||
protected override bool CanSelectMultipleInstances()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
protected override Type CreateCollectionItemType()
|
||||
{
|
||||
return base.CreateCollectionItemType();
|
||||
}
|
||||
protected override object CreateInstance(Type itemType)
|
||||
{
|
||||
TreeListView owner = this.Context.Instance as TreeListView;
|
||||
// create new default fieldname
|
||||
string fieldname;
|
||||
string caption;
|
||||
int cnt = owner.Columns.Count;
|
||||
do
|
||||
{
|
||||
fieldname = "fieldname" + cnt.ToString();
|
||||
caption = "Column_" + cnt.ToString();
|
||||
cnt++;
|
||||
}
|
||||
while (owner.Columns[fieldname] != null);
|
||||
return new TreeListColumn(fieldname, caption);
|
||||
}
|
||||
protected override string GetDisplayText(object value)
|
||||
{
|
||||
string Caption = (string)value.GetType().GetProperty("Caption").GetGetMethod().Invoke(value, null);
|
||||
string Fieldname = (string)value.GetType().GetProperty("Fieldname").GetGetMethod().Invoke(value, null);
|
||||
|
||||
if (Caption.Length > 0)
|
||||
return string.Format("{0} ({1})", Caption, Fieldname);
|
||||
return base.GetDisplayText(value);
|
||||
}
|
||||
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
|
||||
{
|
||||
object result = base.EditValue(context, provider, value);
|
||||
TreeListView owner = this.Context.Instance as TreeListView;
|
||||
owner.Invalidate();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ColumnConverter : ExpandableObjectConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
|
||||
{
|
||||
if (destType == typeof(InstanceDescriptor) || destType == typeof(string))
|
||||
return true;
|
||||
else
|
||||
return base.CanConvertTo(context, destType);
|
||||
}
|
||||
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo info, object value, Type destType)
|
||||
{
|
||||
if (destType == typeof(string))
|
||||
{
|
||||
string Caption = (string)value.GetType().GetProperty("Caption").GetGetMethod().Invoke(value, null);
|
||||
string Fieldname = (string)value.GetType().GetProperty("Fieldname").GetGetMethod().Invoke(value, null);
|
||||
|
||||
return String.Format("{0}, {1}", Caption, Fieldname);
|
||||
}
|
||||
if (destType == typeof(InstanceDescriptor))
|
||||
{
|
||||
ConstructorInfo cinfo = typeof(TreeListColumn).GetConstructor(new Type[] { typeof(string), typeof(string) });
|
||||
|
||||
string Caption = (string)value.GetType().GetProperty("Caption").GetGetMethod().Invoke(value, null);
|
||||
string Fieldname = (string)value.GetType().GetProperty("Fieldname").GetGetMethod().Invoke(value, null);
|
||||
|
||||
return new InstanceDescriptor(cinfo, new object[] {Fieldname, Caption}, false);
|
||||
}
|
||||
return base.ConvertTo(context, info, value, destType);
|
||||
}
|
||||
}
|
||||
class ColumnsTypeConverter : ExpandableObjectConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(TreeListColumnCollection))
|
||||
return true;
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
return "(Columns Collection)";
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Designer for the tree view control.
|
||||
/// </summary>
|
||||
class TreeListViewDesigner : ControlDesigner
|
||||
{
|
||||
IComponentChangeService onChangeService;
|
||||
public override void Initialize(IComponent component)
|
||||
{
|
||||
base.Initialize(component);
|
||||
|
||||
onChangeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
|
||||
if (onChangeService != null)
|
||||
onChangeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged);
|
||||
|
||||
// we need to be notified when columsn have been resized.
|
||||
TreeListView tree = Control as TreeListView;
|
||||
tree.AfterResizingColumn += new MouseEventHandler(OnAfterResizingColumn);
|
||||
}
|
||||
void OnAfterResizingColumn(object sender, MouseEventArgs e)
|
||||
{
|
||||
// This is to notify that component has changed.
|
||||
// This is causing the code InitializeComponent code to be updated
|
||||
RaiseComponentChanged(null, null, null);
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
void OnComponentChanged(object sender, ComponentChangedEventArgs e)
|
||||
{
|
||||
// repaint the control when any properties have changed
|
||||
if(Control != null)
|
||||
Control.Invalidate();
|
||||
}
|
||||
protected override bool GetHitTest(Point point)
|
||||
{
|
||||
// if mouse is over node, columns or scrollbar then return true
|
||||
// which will cause the mouse event to be forwarded to the control
|
||||
TreeListView tree = Control as TreeListView;
|
||||
point = tree.PointToClient(point);
|
||||
|
||||
Node node = tree.CalcHitNode(point);
|
||||
if (node != null)
|
||||
return true;
|
||||
|
||||
TreelistView.HitInfo colinfo = tree.CalcColumnHit(point);
|
||||
if ((int)(colinfo.HitType & HitInfo.eHitType.kColumnHeader) > 0)
|
||||
return true;
|
||||
|
||||
if (tree.HitTestScrollbar(point))
|
||||
return true;
|
||||
return base.GetHitTest(point);
|
||||
}
|
||||
|
||||
protected override void PostFilterProperties(IDictionary properties)
|
||||
{
|
||||
//properties.Remove("Cursor");
|
||||
base.PostFilterProperties(properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,624 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
|
||||
// Taken from http://www.codeproject.com/Articles/23746/TreeView-with-Columns with minor tweaks
|
||||
// and fixes for my purposes.
|
||||
namespace TreelistView
|
||||
{
|
||||
public class HitInfo
|
||||
{
|
||||
public enum eHitType
|
||||
{
|
||||
kColumnHeader = 0x0001,
|
||||
kColumnHeaderResize = 0x0002,
|
||||
}
|
||||
|
||||
public eHitType HitType = 0;
|
||||
public TreeListColumn Column = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DesignTimeVisible(false) prevents the columns from showing in the component tray (bottom of screen)
|
||||
/// If the class implement IComponent it must also implement default (void) constructor and when overriding
|
||||
/// the collection editors CreateInstance the return object must be used (if implementing IComponent), the reason
|
||||
/// is that ISite is needed, and ISite is set when base.CreateInstance is called.
|
||||
/// If no default constructor then the object will not be added to the collection in the initialize.
|
||||
/// In addition if implementing IComponent then name and generatemember is shown in the property grid
|
||||
/// Columns should just be added to the collection, no need for member, so no need to implement IComponent
|
||||
/// </summary>
|
||||
[DesignTimeVisible(false)]
|
||||
[TypeConverter(typeof(ColumnConverter))]
|
||||
public class TreeListColumn
|
||||
{
|
||||
TreeList.TextFormatting m_headerFormat = new TreeList.TextFormatting();
|
||||
TreeList.TextFormatting m_cellFormat = new TreeList.TextFormatting();
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
public TreeList.TextFormatting HeaderFormat
|
||||
{
|
||||
get { return m_headerFormat; }
|
||||
}
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
public TreeList.TextFormatting CellFormat
|
||||
{
|
||||
get { return m_cellFormat; }
|
||||
}
|
||||
|
||||
TreeListColumnCollection m_owner = null;
|
||||
Rectangle m_calculatedRect;
|
||||
int m_visibleIndex = -1;
|
||||
int m_colIndex = -1;
|
||||
int m_width = 50;
|
||||
string m_fieldName = string.Empty;
|
||||
string m_caption = string.Empty;
|
||||
|
||||
bool m_Moving = false;
|
||||
|
||||
internal TreeListColumnCollection Owner
|
||||
{
|
||||
get { return m_owner; }
|
||||
set { m_owner = value; }
|
||||
}
|
||||
internal Rectangle internalCalculatedRect
|
||||
{
|
||||
get { return m_calculatedRect; }
|
||||
set { m_calculatedRect = value; }
|
||||
}
|
||||
internal int internalVisibleIndex
|
||||
{
|
||||
get { return m_visibleIndex; }
|
||||
set { m_visibleIndex = value; }
|
||||
}
|
||||
internal int internalIndex
|
||||
{
|
||||
get { return m_colIndex; }
|
||||
set { m_colIndex = value; }
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public bool Moving
|
||||
{
|
||||
get { return m_Moving; }
|
||||
set
|
||||
{
|
||||
m_Moving = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public Rectangle CalculatedRect
|
||||
{
|
||||
get { return internalCalculatedRect; }
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public TreeListView TreeList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Owner == null)
|
||||
return null;
|
||||
return Owner.Owner;
|
||||
}
|
||||
}
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public Font Font
|
||||
{
|
||||
get { return m_owner.Font; }
|
||||
}
|
||||
public int Width
|
||||
{
|
||||
get { return m_width; }
|
||||
set
|
||||
{
|
||||
if (m_width == value)
|
||||
return;
|
||||
m_width = value;
|
||||
if (m_owner != null && m_owner.DesignMode)
|
||||
m_owner.RecalcVisibleColumsRect();
|
||||
}
|
||||
}
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public string Caption
|
||||
{
|
||||
get { return m_caption; }
|
||||
set
|
||||
{
|
||||
m_caption = value;
|
||||
if (m_owner != null)
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public string Fieldname
|
||||
{
|
||||
get { return m_fieldName; }
|
||||
set
|
||||
{
|
||||
if (m_owner == null || m_owner.DesignMode == false)
|
||||
throw new Exception("Fieldname can only be set at design time, Use Constructor to set programatically");
|
||||
if (value.Length == 0)
|
||||
throw new Exception("empty Fieldname not value");
|
||||
if (m_owner[value] != null)
|
||||
throw new Exception("fieldname already exist in collection");
|
||||
m_fieldName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TreeListColumn(string fieldName)
|
||||
{
|
||||
m_fieldName = fieldName;
|
||||
}
|
||||
public TreeListColumn(string fieldName, string caption)
|
||||
{
|
||||
m_fieldName = fieldName;
|
||||
m_caption = caption;
|
||||
}
|
||||
public TreeListColumn(string fieldName, string caption, int width)
|
||||
{
|
||||
m_fieldName = fieldName;
|
||||
m_caption = caption;
|
||||
m_width = width;
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public int VisibleIndex
|
||||
{
|
||||
get { return internalVisibleIndex; }
|
||||
set
|
||||
{
|
||||
if (m_owner != null)
|
||||
m_owner.SetVisibleIndex(this, value);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public int Index
|
||||
{
|
||||
get { return internalIndex; }
|
||||
}
|
||||
public bool ishot = false;
|
||||
public virtual void Draw(Graphics dc, ColumnHeaderPainter painter, Rectangle r)
|
||||
{
|
||||
painter.DrawHeader(dc, r, this, this.HeaderFormat, ishot, m_Moving);
|
||||
}
|
||||
|
||||
bool m_autoSize = false;
|
||||
float m_autoSizeRatio = 100;
|
||||
int m_autoSizeMinSize;
|
||||
|
||||
[DefaultValue(false)]
|
||||
public bool AutoSize
|
||||
{
|
||||
get { return m_autoSize; }
|
||||
set { m_autoSize = value; }
|
||||
}
|
||||
[DefaultValue(100f)]
|
||||
public float AutoSizeRatio
|
||||
{
|
||||
get { return m_autoSizeRatio; }
|
||||
set { m_autoSizeRatio = value; }
|
||||
}
|
||||
public int AutoSizeMinSize
|
||||
{
|
||||
get { return m_autoSizeMinSize; }
|
||||
set { m_autoSizeMinSize = value; }
|
||||
}
|
||||
int m_calculatedAutoSize;
|
||||
internal int CalculatedAutoSize
|
||||
{
|
||||
get { return m_calculatedAutoSize; }
|
||||
set { m_calculatedAutoSize = value; }
|
||||
}
|
||||
}
|
||||
|
||||
[Description("This is the columns collection")]
|
||||
//[TypeConverterAttribute(typeof(ColumnsTypeConverter))]
|
||||
[Editor(typeof(ColumnCollectionEditor),typeof(System.Drawing.Design.UITypeEditor))]
|
||||
public class TreeListColumnCollection : IList<TreeListColumn>, IList
|
||||
{
|
||||
ColumnHeaderPainter m_painter;
|
||||
TreeList.CollumnSetting m_options;
|
||||
TreeListView m_owner;
|
||||
List<TreeListColumn> m_columns = new List<TreeListColumn>();
|
||||
List<TreeListColumn> m_visibleCols = new List<TreeListColumn>();
|
||||
Dictionary<string, TreeListColumn> m_columnMap = new Dictionary<string,TreeListColumn>();
|
||||
|
||||
[Browsable(false)]
|
||||
public TreeList.CollumnSetting Options
|
||||
{
|
||||
get { return m_options; }
|
||||
}
|
||||
[Browsable(false)]
|
||||
public ColumnHeaderPainter Painter
|
||||
{
|
||||
get { return m_painter; }
|
||||
set { m_painter = value; }
|
||||
}
|
||||
[Browsable(false)]
|
||||
public TreeListView Owner
|
||||
{
|
||||
get { return m_owner; }
|
||||
}
|
||||
[Browsable(false)]
|
||||
public Font Font
|
||||
{
|
||||
get { return m_owner.Font; }
|
||||
}
|
||||
[Browsable(false)]
|
||||
public TreeListColumn[] VisibleColumns
|
||||
{
|
||||
get { return m_visibleCols.ToArray(); }
|
||||
}
|
||||
[Browsable(false)]
|
||||
public int ColumnsWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
int width = 0;
|
||||
foreach (TreeListColumn col in m_visibleCols)
|
||||
{
|
||||
if (col.AutoSize)
|
||||
width += col.CalculatedAutoSize;
|
||||
else
|
||||
width += col.Width;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
}
|
||||
public TreeListColumnCollection(TreeListView owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_options = new TreeList.CollumnSetting(owner);
|
||||
m_painter = new ColumnHeaderPainter(owner);
|
||||
}
|
||||
public TreeListColumn this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_columns[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
m_columns[index] = value;
|
||||
}
|
||||
}
|
||||
public TreeListColumn this[string fieldname]
|
||||
{
|
||||
get
|
||||
{
|
||||
TreeListColumn col;
|
||||
m_columnMap.TryGetValue(fieldname, out col);
|
||||
return col;
|
||||
}
|
||||
}
|
||||
public void SetVisibleIndex(TreeListColumn col, int index)
|
||||
{
|
||||
m_visibleCols.Remove(col);
|
||||
if (index >= 0)
|
||||
{
|
||||
if (index < m_visibleCols.Count)
|
||||
m_visibleCols.Insert(index, col);
|
||||
else
|
||||
m_visibleCols.Add(col);
|
||||
}
|
||||
RecalcVisibleColumsRect();
|
||||
}
|
||||
public HitInfo CalcHitInfo(Point point, int horzOffset)
|
||||
{
|
||||
HitInfo info = new HitInfo();
|
||||
info.Column = CalcHitColumn(point, horzOffset);
|
||||
if ((info.Column != null) && (point.Y < Options.HeaderHeight))
|
||||
{
|
||||
info.HitType |= HitInfo.eHitType.kColumnHeader;
|
||||
int right = info.Column.CalculatedRect.Right - horzOffset;
|
||||
if (info.Column.AutoSize == false || info.Column.internalIndex+1 < m_columns.Count)
|
||||
{
|
||||
if (point.X >= right - 4 && point.X <= right)
|
||||
info.HitType |= HitInfo.eHitType.kColumnHeaderResize;
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
public TreeListColumn CalcHitColumn(Point point, int horzOffset)
|
||||
{
|
||||
if (point.X < Options.LeftMargin)
|
||||
return null;
|
||||
foreach (TreeListColumn col in m_visibleCols)
|
||||
{
|
||||
int left = col.CalculatedRect.Left - horzOffset;
|
||||
int right = col.CalculatedRect.Right - horzOffset;
|
||||
if (point.X >= left && point.X <= right)
|
||||
return col;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void RecalcVisibleColumsRect()
|
||||
{
|
||||
RecalcVisibleColumsRect(false);
|
||||
}
|
||||
public void RecalcVisibleColumsRect(bool isColumnResizing)
|
||||
{
|
||||
if (IsInitializing)
|
||||
return;
|
||||
int x = 0;//m_leftMargin;
|
||||
if (m_owner.RowOptions.ShowHeader)
|
||||
x = m_owner.RowOptions.HeaderWidth;
|
||||
int y = 0;
|
||||
int h = Options.HeaderHeight;
|
||||
int index = 0;
|
||||
foreach(TreeListColumn col in m_columns)
|
||||
{
|
||||
col.internalVisibleIndex = -1;
|
||||
col.internalIndex = index++;
|
||||
}
|
||||
|
||||
// calculate size requierd by fix columns and auto adjusted columns
|
||||
// at the same time calculate total ratio value
|
||||
int widthFixedColumns = 0;
|
||||
int widthAutoSizeColumns = 0;
|
||||
float totalRatio = 0;
|
||||
foreach (TreeListColumn col in m_visibleCols)
|
||||
{
|
||||
if (col.AutoSize)
|
||||
{
|
||||
widthAutoSizeColumns += col.AutoSizeMinSize;
|
||||
totalRatio += col.AutoSizeRatio;
|
||||
}
|
||||
else
|
||||
widthFixedColumns += col.Width;
|
||||
}
|
||||
|
||||
int clientWidth = m_owner.ClientRectangle.Width - m_owner.RowHeaderWidth();
|
||||
// find ratio 'unit' value
|
||||
float remainingWidth = clientWidth - (widthFixedColumns + widthAutoSizeColumns);
|
||||
float ratioUnit = 0;
|
||||
if (totalRatio > 0 && remainingWidth > 0)
|
||||
ratioUnit = remainingWidth / totalRatio;
|
||||
|
||||
for (index = 0; index < m_visibleCols.Count; index++)
|
||||
{
|
||||
TreeListColumn col = m_visibleCols[index];
|
||||
int width = col.Width;
|
||||
if (col.AutoSize)
|
||||
{
|
||||
// if doing column resizing then keep adjustable columns fixed at last width
|
||||
if (m_options.FreezeWhileResizing && isColumnResizing)
|
||||
width = col.CalculatedAutoSize;
|
||||
else
|
||||
width = Math.Max(10, col.AutoSizeMinSize + (int)Math.Round(ratioUnit * col.AutoSizeRatio - 1.0f));
|
||||
col.CalculatedAutoSize = width;
|
||||
}
|
||||
col.internalCalculatedRect = new Rectangle(x, y, width, h);
|
||||
col.internalVisibleIndex = index;
|
||||
x += width;
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
public void Draw(Graphics dc, Rectangle rect, int horzOffset)
|
||||
{
|
||||
foreach (TreeListColumn col in m_visibleCols)
|
||||
{
|
||||
Rectangle r = col.CalculatedRect;
|
||||
r.X -= horzOffset;
|
||||
if (r.Left > rect.Right)
|
||||
break;
|
||||
col.Draw(dc, m_painter, r);
|
||||
}
|
||||
// drwa row header filler
|
||||
if (m_owner.RowOptions.ShowHeader)
|
||||
{
|
||||
Rectangle r = new Rectangle(0, 0, m_owner.RowOptions.HeaderWidth, Options.HeaderHeight);
|
||||
m_painter.DrawHeaderFiller(dc, r);
|
||||
}
|
||||
}
|
||||
public void AddRange(IEnumerable<TreeListColumn> columns)
|
||||
{
|
||||
foreach (TreeListColumn col in columns)
|
||||
Add(col);
|
||||
}
|
||||
/// <summary>
|
||||
/// AddRange(Item[]) is required for the designer.
|
||||
/// </summary>
|
||||
/// <param name="columns"></param>
|
||||
public void AddRange(TreeListColumn[] columns)
|
||||
{
|
||||
foreach (TreeListColumn col in columns)
|
||||
Add(col);
|
||||
}
|
||||
public void Add(TreeListColumn item)
|
||||
{
|
||||
bool designmode = Owner.DesignMode;
|
||||
if (!designmode)
|
||||
{
|
||||
Debug.Assert(m_columnMap.ContainsKey(item.Fieldname) == false);
|
||||
Debug.Assert(item.Owner == null, "column.Owner == null");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_columns.Remove(item);
|
||||
m_visibleCols.Remove(item);
|
||||
}
|
||||
|
||||
item.Owner = this;
|
||||
m_columns.Add(item);
|
||||
m_visibleCols.Add(item);
|
||||
m_columnMap[item.Fieldname] = item;
|
||||
RecalcVisibleColumsRect();
|
||||
//return item;
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
m_columnMap.Clear();
|
||||
m_columns.Clear();
|
||||
m_visibleCols.Clear();
|
||||
}
|
||||
public bool Contains(TreeListColumn item)
|
||||
{
|
||||
return m_columns.Contains(item);
|
||||
}
|
||||
[Browsable(false)]
|
||||
public int Count
|
||||
{
|
||||
get { return m_columns.Count; }
|
||||
}
|
||||
[Browsable(false)]
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
#region IList<TreeListColumn> Members
|
||||
|
||||
public int IndexOf(TreeListColumn item)
|
||||
{
|
||||
return m_columns.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, TreeListColumn item)
|
||||
{
|
||||
m_columns.Insert(index, item);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_columns.Count)
|
||||
{
|
||||
TreeListColumn col = m_columns[index];
|
||||
SetVisibleIndex(col, -1);
|
||||
m_columnMap.Remove(col.Fieldname);
|
||||
}
|
||||
m_columns.RemoveAt(index);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region ICollection<TreeListColumn> Members
|
||||
|
||||
|
||||
public void CopyTo(TreeListColumn[] array, int arrayIndex)
|
||||
{
|
||||
m_columns.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(TreeListColumn item)
|
||||
{
|
||||
SetVisibleIndex(item, -1);
|
||||
m_columnMap.Remove(item.Fieldname);
|
||||
return m_columns.Remove(item);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region IEnumerable<TreeListColumn> Members
|
||||
|
||||
public IEnumerator<TreeListColumn> GetEnumerator()
|
||||
{
|
||||
return m_columns.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region IEnumerable Members
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
#region IList Members
|
||||
int IList.Add(object value)
|
||||
{
|
||||
Add((TreeListColumn)value);
|
||||
return Count - 1;
|
||||
}
|
||||
bool IList.Contains(object value)
|
||||
{
|
||||
return Contains((TreeListColumn)value);
|
||||
}
|
||||
int IList.IndexOf(object value)
|
||||
{
|
||||
return IndexOf((TreeListColumn)value);
|
||||
}
|
||||
void IList.Insert(int index, object value)
|
||||
{
|
||||
Insert(index, (TreeListColumn)value);
|
||||
}
|
||||
|
||||
bool IList.IsFixedSize
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
void IList.Remove(object value)
|
||||
{
|
||||
Remove((TreeListColumn)value);
|
||||
}
|
||||
|
||||
object IList.this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region ICollection Members
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { throw new Exception("The method or operation is not implemented."); }
|
||||
}
|
||||
|
||||
public object SyncRoot
|
||||
{
|
||||
get { throw new Exception("The method or operation is not implemented."); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal bool DesignMode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_owner != null)
|
||||
return m_owner.DesignMode;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal void Invalidate()
|
||||
{
|
||||
if (m_owner != null)
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
bool IsInitializing = false;
|
||||
internal void BeginInit()
|
||||
{
|
||||
IsInitializing = true;
|
||||
}
|
||||
internal void EndInit()
|
||||
{
|
||||
IsInitializing = false;
|
||||
RecalcVisibleColumsRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,334 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
// Taken from http://www.codeproject.com/Articles/23746/TreeView-with-Columns with minor tweaks
|
||||
// and fixes for my purposes.
|
||||
namespace TreelistView.TreeList
|
||||
{
|
||||
[TypeConverterAttribute(typeof(OptionsSettingTypeConverter))]
|
||||
public class TextFormatting
|
||||
{
|
||||
ContentAlignment m_alignment = ContentAlignment.MiddleLeft;
|
||||
Color m_foreColor = SystemColors.ControlText;
|
||||
Color m_backColor = Color.Transparent;
|
||||
Padding m_padding = new Padding(0,0,0,0);
|
||||
public TextFormatFlags GetFormattingFlags()
|
||||
{
|
||||
TextFormatFlags flags = 0;
|
||||
switch (TextAlignment)
|
||||
{
|
||||
case ContentAlignment.TopLeft:
|
||||
flags = TextFormatFlags.Top | TextFormatFlags.Left;
|
||||
break;
|
||||
case ContentAlignment.TopCenter:
|
||||
flags = TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
|
||||
break;
|
||||
case ContentAlignment.TopRight:
|
||||
flags = TextFormatFlags.Top | TextFormatFlags.Right;
|
||||
break;
|
||||
case ContentAlignment.MiddleLeft:
|
||||
flags = TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
|
||||
break;
|
||||
case ContentAlignment.MiddleCenter:
|
||||
flags = TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter;
|
||||
break;
|
||||
case ContentAlignment.MiddleRight:
|
||||
flags = TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
|
||||
break;
|
||||
case ContentAlignment.BottomLeft:
|
||||
flags = TextFormatFlags.Bottom | TextFormatFlags.Left;
|
||||
break;
|
||||
case ContentAlignment.BottomCenter:
|
||||
flags = TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
|
||||
break;
|
||||
case ContentAlignment.BottomRight:
|
||||
flags = TextFormatFlags.Bottom | TextFormatFlags.Right;
|
||||
break;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
[DefaultValue(typeof(Padding), "0,0,0,0")]
|
||||
public Padding Padding
|
||||
{
|
||||
get { return m_padding; }
|
||||
set { m_padding = value; }
|
||||
}
|
||||
[DefaultValue(typeof(ContentAlignment), "MiddleLeft")]
|
||||
public ContentAlignment TextAlignment
|
||||
{
|
||||
get { return m_alignment; }
|
||||
set { m_alignment = value; }
|
||||
}
|
||||
[DefaultValue(typeof(Color), "ControlText")]
|
||||
public Color ForeColor
|
||||
{
|
||||
get { return m_foreColor; }
|
||||
set { m_foreColor = value; }
|
||||
}
|
||||
[DefaultValue(typeof(Color), "Transparent")]
|
||||
public Color BackColor
|
||||
{
|
||||
get { return m_backColor; }
|
||||
set { m_backColor = value; }
|
||||
}
|
||||
public TextFormatting()
|
||||
{
|
||||
}
|
||||
public TextFormatting(TextFormatting aCopy)
|
||||
{
|
||||
m_alignment = aCopy.m_alignment;
|
||||
m_foreColor = aCopy.m_foreColor;
|
||||
m_backColor = aCopy.m_backColor;
|
||||
m_padding = aCopy.m_padding;
|
||||
}
|
||||
}
|
||||
|
||||
[TypeConverterAttribute(typeof(OptionsSettingTypeConverter))]
|
||||
public class ViewSetting
|
||||
{
|
||||
TreeListView m_owner;
|
||||
BorderStyle m_borderStyle = BorderStyle.None;
|
||||
int m_indent = 16;
|
||||
bool m_showLine = true;
|
||||
bool m_showPlusMinus = true;
|
||||
bool m_showGridLines = true;
|
||||
bool m_rearrangeableColumns = false;
|
||||
bool m_hoverHand = true;
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(int), "16")]
|
||||
public int Indent
|
||||
{
|
||||
get { return m_indent; }
|
||||
set
|
||||
{
|
||||
m_indent = value;
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "True")]
|
||||
public bool ShowLine
|
||||
{
|
||||
get { return m_showLine; }
|
||||
set
|
||||
{
|
||||
m_showLine = value;
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "True")]
|
||||
public bool ShowPlusMinus
|
||||
{
|
||||
get { return m_showPlusMinus; }
|
||||
set
|
||||
{
|
||||
m_showPlusMinus = value;
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "True")]
|
||||
public bool ShowGridLines
|
||||
{
|
||||
get { return m_showGridLines; }
|
||||
set
|
||||
{
|
||||
m_showGridLines = value;
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "False")]
|
||||
public bool UserRearrangeableColumns
|
||||
{
|
||||
get { return m_rearrangeableColumns; }
|
||||
set
|
||||
{
|
||||
m_rearrangeableColumns = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "True")]
|
||||
public bool HoverHandTreeColumn
|
||||
{
|
||||
get { return m_hoverHand; }
|
||||
set
|
||||
{
|
||||
m_hoverHand = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Appearance")]
|
||||
[DefaultValue(typeof(BorderStyle), "None")]
|
||||
public BorderStyle BorderStyle
|
||||
{
|
||||
get { return m_borderStyle; }
|
||||
set
|
||||
{
|
||||
if (m_borderStyle != value)
|
||||
{
|
||||
m_borderStyle = value;
|
||||
m_owner.internalUpdateStyles();
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ViewSetting(TreeListView owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
}
|
||||
}
|
||||
|
||||
[TypeConverterAttribute(typeof(OptionsSettingTypeConverter))]
|
||||
public class CollumnSetting
|
||||
{
|
||||
bool m_FreezeWhileResizing = false;
|
||||
int m_leftMargin = 5;
|
||||
int m_headerHeight = 20;
|
||||
TreeListView m_owner;
|
||||
|
||||
[DefaultValue(false)]
|
||||
public bool FreezeWhileResizing
|
||||
{
|
||||
get { return m_FreezeWhileResizing; }
|
||||
set
|
||||
{
|
||||
m_FreezeWhileResizing = value;
|
||||
}
|
||||
}
|
||||
[DefaultValue(5)]
|
||||
public int LeftMargin
|
||||
{
|
||||
get { return m_leftMargin; }
|
||||
set
|
||||
{
|
||||
m_leftMargin = value;
|
||||
m_owner.Columns.RecalcVisibleColumsRect();
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
[DefaultValue(20)]
|
||||
public int HeaderHeight
|
||||
{
|
||||
get { return m_headerHeight; }
|
||||
set
|
||||
{
|
||||
m_headerHeight = value;
|
||||
m_owner.Columns.RecalcVisibleColumsRect();
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
public CollumnSetting(TreeListView owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
}
|
||||
}
|
||||
|
||||
[TypeConverterAttribute(typeof(OptionsSettingTypeConverter))]
|
||||
public class RowSetting
|
||||
{
|
||||
TreeListView m_owner;
|
||||
bool m_showHeader = true;
|
||||
bool m_hoverHighlight = false;
|
||||
int m_headerWidth = 15;
|
||||
int m_itemHeight = 16;
|
||||
[DefaultValue(true)]
|
||||
public bool ShowHeader
|
||||
{
|
||||
get { return m_showHeader; }
|
||||
set
|
||||
{
|
||||
if (m_showHeader == value)
|
||||
return;
|
||||
m_showHeader = value;
|
||||
m_owner.Columns.RecalcVisibleColumsRect();
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
[DefaultValue(false)]
|
||||
public bool HoverHighlight
|
||||
{
|
||||
get { return m_hoverHighlight; }
|
||||
set
|
||||
{
|
||||
if (m_hoverHighlight == value)
|
||||
return;
|
||||
m_hoverHighlight = value;
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
[DefaultValue(15)]
|
||||
public int HeaderWidth
|
||||
{
|
||||
get { return m_headerWidth; }
|
||||
set
|
||||
{
|
||||
if (m_headerWidth == value)
|
||||
return;
|
||||
m_headerWidth = value;
|
||||
m_owner.Columns.RecalcVisibleColumsRect();
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(int), "16")]
|
||||
public int ItemHeight
|
||||
{
|
||||
get { return m_itemHeight; }
|
||||
set
|
||||
{
|
||||
m_itemHeight = value;
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public RowSetting(TreeListView owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
}
|
||||
}
|
||||
|
||||
class OptionsSettingTypeConverter : ExpandableObjectConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(ViewSetting))
|
||||
return true;
|
||||
if (destinationType == typeof(RowSetting))
|
||||
return true;
|
||||
if (destinationType == typeof(CollumnSetting))
|
||||
return true;
|
||||
if (destinationType == typeof(TextFormatting))
|
||||
return true;
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string) && value.GetType() == typeof(ViewSetting))
|
||||
return "(View Options)";
|
||||
if (destinationType == typeof(string) && value.GetType() == typeof(RowSetting))
|
||||
return "(Row Header Options)";
|
||||
if (destinationType == typeof(string) && value.GetType() == typeof(CollumnSetting))
|
||||
return "(Columns Options)";
|
||||
if (destinationType == typeof(string) && value.GetType() == typeof(TextFormatting))
|
||||
return "(Formatting)";
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Taken from http://www.codeproject.com/Articles/23746/TreeView-with-Columns with minor tweaks
|
||||
// and fixes for my purposes.
|
||||
namespace TreelistView
|
||||
{
|
||||
public class VisualStyleItemBackground // can't find system provided visual style for this.
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class RECT
|
||||
{
|
||||
public int left;
|
||||
public int top;
|
||||
public int right;
|
||||
public int bottom;
|
||||
public RECT()
|
||||
{
|
||||
}
|
||||
|
||||
public RECT(Rectangle r)
|
||||
{
|
||||
this.left = r.X;
|
||||
this.top = r.Y;
|
||||
this.right = r.Right;
|
||||
this.bottom = r.Bottom;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet=CharSet.Auto)]
|
||||
public static extern int DrawThemeBackground(IntPtr hTheme, IntPtr hdc, int partId, int stateId, [In] RECT pRect, [In] RECT pClipRect);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet=CharSet.Auto)]
|
||||
public static extern IntPtr OpenThemeData(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszClassList);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet=CharSet.Auto)]
|
||||
public static extern int CloseThemeData(IntPtr hTheme);
|
||||
|
||||
//http://www.ookii.org/misc/vsstyle.h
|
||||
//http://msdn2.microsoft.com/en-us/library/bb773210(VS.85).aspx
|
||||
enum ITEMSTATES
|
||||
{
|
||||
LBPSI_HOT = 1,
|
||||
LBPSI_HOTSELECTED = 2,
|
||||
LBPSI_SELECTED = 3,
|
||||
LBPSI_SELECTEDNOTFOCUS = 4,
|
||||
};
|
||||
|
||||
enum LISTBOXPARTS
|
||||
{
|
||||
LBCP_BORDER_HSCROLL = 1,
|
||||
LBCP_BORDER_HVSCROLL = 2,
|
||||
LBCP_BORDER_NOSCROLL = 3,
|
||||
LBCP_BORDER_VSCROLL = 4,
|
||||
LBCP_ITEM = 5,
|
||||
};
|
||||
|
||||
public enum Style
|
||||
{
|
||||
Normal,
|
||||
Inactive, // when not focused
|
||||
}
|
||||
Style m_style;
|
||||
public VisualStyleItemBackground(Style style)
|
||||
{
|
||||
m_style = style;
|
||||
}
|
||||
public void DrawBackground(Control owner, Graphics dc, Rectangle r, Color col)
|
||||
{
|
||||
/*
|
||||
IntPtr themeHandle = OpenThemeData(owner.Handle, "Explorer");
|
||||
if (themeHandle != IntPtr.Zero)
|
||||
{
|
||||
DrawThemeBackground(themeHandle, dc.GetHdc(), (int)LISTBOXPARTS.LBCP_ITEM, (int)ITEMSTATES.LBPSI_SELECTED, new RECT(r), new RECT(r));
|
||||
dc.ReleaseHdc();
|
||||
CloseThemeData(themeHandle);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
Pen pen = new Pen(col);
|
||||
GraphicsPath path = new GraphicsPath();
|
||||
path.AddLine(r.Left + 2, r.Top, r.Right - 2, r.Top);
|
||||
path.AddLine(r.Right, r.Top + 2, r.Right, r.Bottom - 2);
|
||||
path.AddLine(r.Right - 2, r.Bottom, r.Left + 2, r.Bottom);
|
||||
path.AddLine(r.Left, r.Bottom - 2, r.Left, r.Top + 2);
|
||||
path.CloseFigure();
|
||||
dc.DrawPath(pen, path);
|
||||
|
||||
//r.Inflate(-1, -1);
|
||||
LinearGradientBrush brush = new LinearGradientBrush(r, Color.FromArgb(120, col), col, 90);
|
||||
dc.FillRectangle(brush, r);
|
||||
// for some reason in some cases the 'white' end of the gradient brush is drawn with the starting color
|
||||
// therefore this redraw of the 'top' line of the rectangle
|
||||
//dc.DrawLine(Pens.White, r.Left + 1, r.Top, r.Right - 1, r.Top);
|
||||
|
||||
pen.Dispose();
|
||||
brush.Dispose();
|
||||
path.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public delegate string CellDataToString(TreeListColumn column, object data);
|
||||
|
||||
public class CellPainter
|
||||
{
|
||||
public static Rectangle AdjustRectangle(Rectangle r, Padding padding)
|
||||
{
|
||||
r.X += padding.Left;
|
||||
r.Width -= padding.Left + padding.Right;
|
||||
r.Y += padding.Top;
|
||||
r.Height -= padding.Top + padding.Bottom;
|
||||
return r;
|
||||
}
|
||||
protected TreeListView m_owner;
|
||||
protected CellDataToString m_converter = null;
|
||||
|
||||
public CellDataToString CellDataConverter
|
||||
{
|
||||
get { return m_converter; }
|
||||
set { m_converter = value; }
|
||||
}
|
||||
|
||||
public CellPainter(TreeListView owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
}
|
||||
public virtual void DrawSelectionBackground(Graphics dc, Rectangle nodeRect, Node node)
|
||||
{
|
||||
Point mousePoint = m_owner.PointToClient(Cursor.Position);
|
||||
Node hoverNode = m_owner.CalcHitNode(mousePoint);
|
||||
|
||||
if (m_owner.NodesSelection.Contains(node) || m_owner.FocusedNode == node)
|
||||
{
|
||||
Color col = m_owner.Focused ? SystemColors.Highlight : SystemColors.ControlLight;
|
||||
|
||||
if (!Application.RenderWithVisualStyles)
|
||||
{
|
||||
// have to fill the solid background only before the node is painted
|
||||
dc.FillRectangle(SystemBrushes.FromSystemColor(col), nodeRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
col = m_owner.Focused ? SystemColors.Highlight : Color.FromArgb(180, SystemColors.ControlDark);
|
||||
|
||||
// have to draw the transparent background after the node is painted
|
||||
VisualStyleItemBackground.Style style = VisualStyleItemBackground.Style.Normal;
|
||||
if (m_owner.Focused == false)
|
||||
style = VisualStyleItemBackground.Style.Inactive;
|
||||
VisualStyleItemBackground rendere = new VisualStyleItemBackground(style);
|
||||
rendere.DrawBackground(m_owner, dc, nodeRect, col);
|
||||
}
|
||||
}
|
||||
else if (hoverNode == node && m_owner.RowOptions.HoverHighlight)
|
||||
{
|
||||
Color col = SystemColors.ControlLight;
|
||||
|
||||
if (!Application.RenderWithVisualStyles)
|
||||
{
|
||||
// have to fill the solid background only before the node is painted
|
||||
dc.FillRectangle(SystemBrushes.FromSystemColor(col), nodeRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// have to draw the transparent background after the node is painted
|
||||
VisualStyleItemBackground.Style style = VisualStyleItemBackground.Style.Normal;
|
||||
if (m_owner.Focused == false)
|
||||
style = VisualStyleItemBackground.Style.Inactive;
|
||||
VisualStyleItemBackground rendere = new VisualStyleItemBackground(style);
|
||||
rendere.DrawBackground(m_owner, dc, nodeRect, col);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_owner.Focused && (m_owner.FocusedNode == node))
|
||||
{
|
||||
nodeRect.Height += 1;
|
||||
nodeRect.Inflate(-1,-1);
|
||||
ControlPaint.DrawFocusRectangle(dc, nodeRect);
|
||||
}
|
||||
}
|
||||
public virtual void PaintCellBackground(Graphics dc,
|
||||
Rectangle cellRect,
|
||||
Node node,
|
||||
TreeListColumn column,
|
||||
TreeList.TextFormatting format,
|
||||
object data)
|
||||
{
|
||||
Color c = Color.Transparent;
|
||||
|
||||
Point mousePoint = m_owner.PointToClient(Cursor.Position);
|
||||
Node hoverNode = m_owner.CalcHitNode(mousePoint);
|
||||
|
||||
if (format.BackColor != Color.Transparent)
|
||||
c = format.BackColor;
|
||||
|
||||
if (node.BackColor != Color.Transparent)
|
||||
c = node.BackColor;
|
||||
|
||||
if (!m_owner.NodesSelection.Contains(node) && m_owner.FocusedNode != node &&
|
||||
!(hoverNode == node && m_owner.RowOptions.HoverHighlight) &&
|
||||
node.DefaultBackColor != Color.Transparent)
|
||||
c = node.DefaultBackColor;
|
||||
|
||||
if (c != Color.Transparent)
|
||||
{
|
||||
Rectangle r = cellRect;
|
||||
r.X -= Math.Max(0, column.CalculatedRect.Width - cellRect.Width);
|
||||
r.Width += Math.Max(0, column.CalculatedRect.Width - cellRect.Width);
|
||||
SolidBrush brush = new SolidBrush(c);
|
||||
dc.FillRectangle(brush, r);
|
||||
brush.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PaintCellText(Graphics dc,
|
||||
Rectangle cellRect,
|
||||
Node node,
|
||||
TreeListColumn column,
|
||||
TreeList.TextFormatting format,
|
||||
object data)
|
||||
{
|
||||
if (data != null)
|
||||
{
|
||||
cellRect = AdjustRectangle(cellRect, format.Padding);
|
||||
//dc.DrawRectangle(Pens.Black, cellRect);
|
||||
|
||||
Color color = format.ForeColor;
|
||||
if (m_owner.FocusedNode == node && Application.RenderWithVisualStyles == false && m_owner.Focused)
|
||||
color = SystemColors.HighlightText;
|
||||
TextFormatFlags flags= TextFormatFlags.EndEllipsis | format.GetFormattingFlags();
|
||||
|
||||
Font f = m_owner.Font;
|
||||
Font disposefont = null;
|
||||
|
||||
if(node.Bold && node.Italic)
|
||||
disposefont = f = new Font(f, FontStyle.Bold|FontStyle.Italic);
|
||||
else if (node.Bold)
|
||||
disposefont = f = new Font(f, FontStyle.Bold);
|
||||
else if (node.Italic)
|
||||
disposefont = f = new Font(f, FontStyle.Italic);
|
||||
|
||||
string datastring = "";
|
||||
|
||||
if(m_converter != null)
|
||||
datastring = m_converter(column, data);
|
||||
else
|
||||
datastring = data.ToString();
|
||||
|
||||
TextRenderer.DrawText(dc, datastring, f, cellRect, color, flags);
|
||||
|
||||
if (disposefont != null) disposefont.Dispose();
|
||||
}
|
||||
}
|
||||
public virtual void PaintCellPlusMinus(Graphics dc, Rectangle glyphRect, Node node, TreeListColumn column, TreeList.TextFormatting format)
|
||||
{
|
||||
if (!Application.RenderWithVisualStyles)
|
||||
{
|
||||
// find square rect first
|
||||
int diff = glyphRect.Height-glyphRect.Width;
|
||||
glyphRect.Y += diff/2;
|
||||
glyphRect.Height -= diff;
|
||||
|
||||
// draw 8x8 box centred
|
||||
while (glyphRect.Height > 8)
|
||||
{
|
||||
glyphRect.Height -= 2;
|
||||
glyphRect.Y += 1;
|
||||
glyphRect.X += 1;
|
||||
}
|
||||
|
||||
// make a box
|
||||
glyphRect.Width = glyphRect.Height;
|
||||
|
||||
// clear first
|
||||
SolidBrush brush = new SolidBrush(format.BackColor);
|
||||
if (format.BackColor == Color.Transparent)
|
||||
brush = new SolidBrush(m_owner.BackColor);
|
||||
dc.FillRectangle(brush, glyphRect);
|
||||
brush.Dispose();
|
||||
|
||||
// draw outline
|
||||
Pen p = new Pen(SystemColors.ControlDark);
|
||||
dc.DrawRectangle(p, glyphRect);
|
||||
p.Dispose();
|
||||
|
||||
p = new Pen(SystemColors.ControlText);
|
||||
|
||||
// reduce box for internal lines
|
||||
glyphRect.X += 2; glyphRect.Y += 2;
|
||||
glyphRect.Width -= 4; glyphRect.Height -= 4;
|
||||
|
||||
// draw horizontal line always
|
||||
dc.DrawLine(p, glyphRect.X, glyphRect.Y + glyphRect.Height / 2, glyphRect.X + glyphRect.Width, glyphRect.Y + glyphRect.Height / 2);
|
||||
|
||||
// draw vertical line if this should be a +
|
||||
if(!node.Expanded)
|
||||
dc.DrawLine(p, glyphRect.X + glyphRect.Width / 2, glyphRect.Y, glyphRect.X + glyphRect.Width / 2, glyphRect.Y + glyphRect.Height);
|
||||
|
||||
p.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
VisualStyleElement element = VisualStyleElement.TreeView.Glyph.Closed;
|
||||
if (node.Expanded)
|
||||
element = VisualStyleElement.TreeView.Glyph.Opened;
|
||||
|
||||
if (VisualStyleRenderer.IsElementDefined(element))
|
||||
{
|
||||
VisualStyleRenderer renderer = new VisualStyleRenderer(element);
|
||||
renderer.DrawBackground(dc, glyphRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class ColumnHeaderPainter
|
||||
{
|
||||
TreeListView m_owner;
|
||||
public ColumnHeaderPainter(TreeListView owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
}
|
||||
|
||||
public static Rectangle AdjustRectangle(Rectangle r, Padding padding)
|
||||
{
|
||||
r.X += padding.Left;
|
||||
r.Width -= padding.Left + padding.Right;
|
||||
r.Y += padding.Top;
|
||||
r.Height -= padding.Top + padding.Bottom;
|
||||
return r;
|
||||
}
|
||||
public virtual void DrawHeaderFiller(Graphics dc, Rectangle r)
|
||||
{
|
||||
if (!Application.RenderWithVisualStyles)
|
||||
{
|
||||
ControlPaint.DrawButton(dc, r, ButtonState.Flat);
|
||||
return;
|
||||
}
|
||||
VisualStyleElement element = VisualStyleElement.Header.Item.Normal;
|
||||
if (VisualStyleRenderer.IsElementDefined(element))
|
||||
{
|
||||
VisualStyleRenderer renderer = new VisualStyleRenderer(element);
|
||||
renderer.DrawBackground(dc, r);
|
||||
}
|
||||
}
|
||||
public void DrawHeaderText(Graphics dc, Rectangle cellRect, TreeListColumn column, TreeList.TextFormatting format)
|
||||
{
|
||||
Color color = format.ForeColor;
|
||||
TextFormatFlags flags = TextFormatFlags.EndEllipsis | format.GetFormattingFlags();
|
||||
TextRenderer.DrawText(dc, column.Caption, column.Font, cellRect, color, flags);
|
||||
}
|
||||
public virtual void DrawHeader(Graphics dc, Rectangle cellRect, TreeListColumn column, TreeList.TextFormatting format, bool isHot, bool highlight)
|
||||
{
|
||||
Rectangle textRect = AdjustRectangle(cellRect, format.Padding);
|
||||
if (!Application.RenderWithVisualStyles)
|
||||
{
|
||||
ControlPaint.DrawButton(dc, cellRect,
|
||||
m_owner.ViewOptions.UserRearrangeableColumns && highlight ? ButtonState.Pushed : ButtonState.Flat);
|
||||
DrawHeaderText(dc, textRect, column, format);
|
||||
return;
|
||||
}
|
||||
VisualStyleElement element = VisualStyleElement.Header.Item.Normal;
|
||||
if (isHot || highlight)
|
||||
element = VisualStyleElement.Header.Item.Hot;
|
||||
if (VisualStyleRenderer.IsElementDefined(element))
|
||||
{
|
||||
VisualStyleRenderer renderer = new VisualStyleRenderer(element);
|
||||
renderer.DrawBackground(dc, cellRect);
|
||||
|
||||
if (format.BackColor != Color.Transparent)
|
||||
{
|
||||
SolidBrush brush = new SolidBrush(format.BackColor);
|
||||
dc.FillRectangle(brush, cellRect);
|
||||
brush.Dispose();
|
||||
}
|
||||
//dc.DrawRectangle(Pens.Black, cellRect);
|
||||
|
||||
DrawHeaderText(dc, textRect, column, format);
|
||||
}
|
||||
}
|
||||
public virtual void DrawVerticalGridLines(TreeListColumnCollection columns, Graphics dc, Rectangle r, int hScrollOffset)
|
||||
{
|
||||
foreach (TreeListColumn col in columns.VisibleColumns)
|
||||
{
|
||||
int rightPos = col.CalculatedRect.Right - hScrollOffset;
|
||||
if (rightPos < 0)
|
||||
continue;
|
||||
Pen p = new Pen(columns.Owner.GridLineColour);
|
||||
dc.DrawLine(p, rightPos, r.Top, rightPos, r.Bottom);
|
||||
p.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
public class RowPainter
|
||||
{
|
||||
public void DrawHeader(Graphics dc, Rectangle r, bool isHot)
|
||||
{
|
||||
if (!Application.RenderWithVisualStyles)
|
||||
{
|
||||
if (r.Width > 0 && r.Height > 0)
|
||||
{
|
||||
ControlPaint.DrawButton(dc, r, ButtonState.Flat);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VisualStyleElement element = VisualStyleElement.Header.Item.Normal;
|
||||
if (isHot)
|
||||
element = VisualStyleElement.Header.Item.Hot;
|
||||
if (VisualStyleRenderer.IsElementDefined(element))
|
||||
{
|
||||
VisualStyleRenderer renderer = new VisualStyleRenderer(element);
|
||||
renderer.DrawBackground(dc, r);
|
||||
}
|
||||
}
|
||||
public void DrawHorizontalGridLine(Graphics dc, Rectangle r, Color col)
|
||||
{
|
||||
Pen p = new Pen(col);
|
||||
dc.DrawLine(p, r.Left, r.Bottom, r.Right, r.Bottom);
|
||||
p.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user