openDecal/Managed/Decal.DecalControls/ListImpl.cs
erik d1442e3747 Initial commit: Complete open-source Decal rebuild
All 5 phases of the open-source Decal rebuild:

Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters
  - Decal.Core, DecalControls, DecalRender, D3DService
Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL
Phase 4: DenAgent WinForms tray application
Phase 5: WiX installer and build script

25 C# projects building with 0 errors.
Native C++ projects require VS 2022 + Windows SDK (x86).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 18:27:56 +01:00

129 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Core;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("3839008F-AF5B-43FC-9F6A-3376B99E3DAF")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.IListEvents\0\0")]
[ProgId("DecalControls.List")]
public class ListImpl : ControlBase, IList
{
public event IListEvents_DestroyEventHandler Destroy;
public event IListEvents_ChangeEventHandler Change;
private readonly List<IListColumn> _columns = new List<IListColumn>();
private readonly List<object[]> _rows = new List<object[]>();
private int _scrollPosition;
private bool _autoScroll;
private int _accessRow, _accessCol;
// IListDisp
public int AddRow()
{
int totalDataCols = 0;
foreach (var col in _columns)
totalDataCols += col.DataColumns;
_rows.Add(new object[Math.Max(1, totalDataCols)]);
if (_autoScroll)
_scrollPosition = Math.Max(0, _rows.Count - 1);
Invalidate();
return _rows.Count - 1;
}
public void DeleteRow(int nIndex)
{
if (nIndex >= 0 && nIndex < _rows.Count)
{
_rows.RemoveAt(nIndex);
Invalidate();
}
}
public object Data
{
get
{
if (_accessRow >= 0 && _accessRow < _rows.Count)
{
var row = _rows[_accessRow];
if (_accessCol >= 0 && _accessCol < row.Length)
return row[_accessCol];
}
return null;
}
set
{
if (_accessRow >= 0 && _accessRow < _rows.Count)
{
var row = _rows[_accessRow];
if (_accessCol >= 0 && _accessCol < row.Length)
{
row[_accessCol] = value;
Invalidate();
Change?.Invoke(ID, _accessCol, _accessRow);
}
}
}
}
public int RowEstimate { set { } }
public int Count => _rows.Count;
public int ColumnWidth
{
get => 0;
set { }
}
public int Color { get; set; }
public bool AutoScroll { get => _autoScroll; set => _autoScroll = value; }
public int ScrollPosition { get => _scrollPosition; set { _scrollPosition = value; Invalidate(); } }
public void Clear()
{
_rows.Clear();
_scrollPosition = 0;
Invalidate();
}
public void InsertRow(int lIndex)
{
int totalDataCols = 0;
foreach (var col in _columns)
totalDataCols += col.DataColumns;
if (lIndex < 0) lIndex = 0;
if (lIndex > _rows.Count) lIndex = _rows.Count;
_rows.Insert(lIndex, new object[Math.Max(1, totalDataCols)]);
Invalidate();
}
public void JumpToPosition(int newVal)
{
_scrollPosition = newVal;
Invalidate();
}
public int CountCols => _columns.Count;
// IList
public int AddColumn(IListColumn pNewColumn)
{
_columns.Add(pNewColumn);
return _columns.Count - 1;
}
public tagRECT CellRect => default;
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}