init
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using Hi.Native;
|
||||
using Hi.Disp;
|
||||
using System.Collections.Generic;
|
||||
using Hi.Geom;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Hi.WinForm.Disp
|
||||
{
|
||||
/// <summary>
|
||||
/// Window Form Displayer.
|
||||
/// </summary>
|
||||
public partial class RenderingCanvas : UserControl
|
||||
{
|
||||
#region Core_Properties
|
||||
/// <summary>
|
||||
/// <see cref="DispEngine"/>.
|
||||
/// </summary>
|
||||
public DispEngine DispEngine { get; }
|
||||
|
||||
// Constants and structures for WM_TOUCH
|
||||
private const int WM_TOUCH = 0x0240;
|
||||
private const int TOUCHEVENTF_MOVE = 0x0001;
|
||||
private const int TOUCHEVENTF_DOWN = 0x0002;
|
||||
private const int TOUCHEVENTF_UP = 0x0004;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct TOUCHINPUT
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public IntPtr hSource;
|
||||
public int dwID;
|
||||
public int dwFlags;
|
||||
public int dwMask;
|
||||
public int dwTime;
|
||||
public IntPtr dwExtraInfo;
|
||||
public int cxContact;
|
||||
public int cyContact;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool RegisterTouchWindow(IntPtr hWnd, uint ulFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool GetTouchInputInfo(IntPtr hTouchInput, int cInputs, [In, Out] TOUCHINPUT[] pInputs, int cbSize);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern void CloseTouchInputHandle(IntPtr lParam);
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
/// <summary>
|
||||
/// Ctor.
|
||||
/// </summary>
|
||||
/// <param name="displayees">displayees</param>
|
||||
public unsafe RenderingCanvas(params IDisplayee[] displayees)
|
||||
{
|
||||
// Configure the control's visual styles
|
||||
SetStyle(ControlStyles.Selectable, true);
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
|
||||
SetStyle(ControlStyles.ContainerControl, false);
|
||||
SetStyle(ControlStyles.ResizeRedraw, false);
|
||||
DoubleBuffered = true;
|
||||
|
||||
InitializeComponent();
|
||||
Dock = DockStyle.Fill;
|
||||
|
||||
// Connect event handlers for user input and window events
|
||||
this.Resize += RenderingCanvas_Resize;
|
||||
this.VisibleChanged += RenderingCanvas_VisibleChanged;
|
||||
this.MouseMove += RenderingCanvas_MouseMove;
|
||||
this.MouseDown += RenderingCanvas_MouseDown;
|
||||
this.MouseUp += RenderingCanvas_MouseUp;
|
||||
this.MouseWheel += RenderingCanvas_MouseWheel;
|
||||
this.KeyDown += RenderingCanvas_KeyDown;
|
||||
this.KeyUp += RenderingCanvas_KeyUp;
|
||||
|
||||
// Add focus event handler
|
||||
this.GotFocus += RenderingCanvas_GotFocus;
|
||||
this.HandleCreated += OnHandleCreated;
|
||||
|
||||
// Enable touch input and click events for the control
|
||||
this.SetStyle(ControlStyles.StandardClick, true);
|
||||
this.SetStyle(ControlStyles.StandardDoubleClick, true);
|
||||
this.TabStop = true;
|
||||
|
||||
// Initialize the DispEngine with provided displayees
|
||||
DispEngine = new DispEngine(displayees);
|
||||
DispEngine.BackgroundColor = new Vec3d(0.1, 0.1, 0.5);
|
||||
DispEngine.BackgroundOpacity = 0.1;
|
||||
DispEngine.SetViewToHomeView();
|
||||
DispEngine.ImageRequestAfterBufferSwapped += DispEngine_ImageRequestAfterBufferSwapped;
|
||||
|
||||
// Set initial size and start the rendering engine
|
||||
this.Size = new System.Drawing.Size(500, 300);
|
||||
DispEngine.Start(this.ClientSize.Width, this.ClientSize.Height);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Win32_Message_Handling
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (m.Msg == WM_TOUCH)
|
||||
{
|
||||
HandleTouchInput(m.WParam, m.LParam);
|
||||
return;
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
private void OnHandleCreated(object sender, EventArgs e)
|
||||
{
|
||||
// Register window to receive touch messages
|
||||
RegisterTouchWindow(this.Handle, 0);
|
||||
}
|
||||
|
||||
private void HandleTouchInput(IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
int inputCount = wParam.ToInt32();
|
||||
TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount];
|
||||
|
||||
if (!GetTouchInputInfo(lParam, inputCount, inputs, Marshal.SizeOf(typeof(TOUCHINPUT))))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < inputCount; i++)
|
||||
{
|
||||
TOUCHINPUT ti = inputs[i];
|
||||
int touchId = ti.dwID;
|
||||
|
||||
// Convert touch coordinates to client coordinates
|
||||
Point touchPoint = PointToClient(new Point(ti.x / 100, ti.y / 100));
|
||||
|
||||
if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0)
|
||||
{
|
||||
// Touch down event
|
||||
DispEngine.TouchDown(touchId, touchPoint.X, touchPoint.Y);
|
||||
this.Focus();
|
||||
}
|
||||
else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0)
|
||||
{
|
||||
// Touch move event
|
||||
DispEngine.TouchMove(touchId, touchPoint.X, touchPoint.Y);
|
||||
}
|
||||
else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0)
|
||||
{
|
||||
// Touch up event
|
||||
DispEngine.TouchUp(touchId);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseTouchInputHandle(lParam);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Cleanup
|
||||
/// <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))
|
||||
{
|
||||
// Dispose the DispEngine to free resources
|
||||
DispEngine.Dispose();
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DispEngine_Rendering
|
||||
private unsafe void DispEngine_ImageRequestAfterBufferSwapped(byte* bgra_unsignedbyte_pixels, int w, int h)
|
||||
{
|
||||
// Create a bitmap from the raw pixel data provided by DispEngine
|
||||
Bitmap bitmap;
|
||||
bitmap = new Bitmap(new Bitmap(w, h, w * 4,
|
||||
PixelFormat.Format32bppArgb, new IntPtr(bgra_unsignedbyte_pixels)));
|
||||
|
||||
// Update the background image and dispose the previous one
|
||||
Image pre = this.BackgroundImage;
|
||||
this.BackgroundImage = bitmap;
|
||||
pre?.Dispose();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Window_Events
|
||||
private void RenderingCanvas_Resize(object sender, EventArgs e)
|
||||
{
|
||||
// Notify DispEngine of size changes
|
||||
DispEngine.Resize(this.ClientSize.Width, this.ClientSize.Height);
|
||||
}
|
||||
|
||||
private void RenderingCanvas_VisibleChanged(object sender, EventArgs e)
|
||||
{
|
||||
// Update visibility state in DispEngine
|
||||
DispEngine.IsVisible = this.Visible;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Mouse_Events
|
||||
private void RenderingCanvas_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
// Update mouse position and handle drag transforms
|
||||
DispEngine.MouseMove(e.Location.X, e.Location.Y);
|
||||
DispEngine.MouseDragTransform(e.Location.X, e.Location.Y,
|
||||
new mouse_button_table__transform_view_by_mouse_drag_t()
|
||||
{
|
||||
LEFT_BUTTON = (long)MouseButtons.Left,
|
||||
RIGHT_BUTTON = (long)MouseButtons.Right
|
||||
});
|
||||
}
|
||||
|
||||
private void RenderingCanvas_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
// Handle mouse button press
|
||||
DispEngine.MouseButtonDown((long)e.Button);
|
||||
this.Focus();
|
||||
}
|
||||
|
||||
private void RenderingCanvas_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
// Handle mouse button release
|
||||
DispEngine.MouseButtonUp((long)e.Button);
|
||||
}
|
||||
|
||||
private void RenderingCanvas_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
// Handle mouse wheel for zoom operations
|
||||
DispEngine.MouseWheel(0, e.Delta / 120);
|
||||
DispEngine.MouseWheelTransform(0, e.Delta / 120);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Keyboard_Events
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsInputKey(Keys keyData)
|
||||
{
|
||||
//since in default, arrow does not trigger key event(keyDown and keyUp).
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RenderingCanvas_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
Focus();
|
||||
DispEngine.KeyDown((long)e.KeyData);
|
||||
|
||||
// Map specific keys for view transformation
|
||||
long key = (long)e.KeyData;
|
||||
if (key == (long)Keys.LShiftKey || key == (long)Keys.RShiftKey || key == (long)Keys.ShiftKey)
|
||||
key = (long)Keys.Shift;
|
||||
|
||||
DispEngine.KeyDownTransform(key, new key_table__transform_view_by_key_pressing_t()
|
||||
{
|
||||
HOME = (long)Keys.Home,
|
||||
PAGE_UP = (long)Keys.PageUp,
|
||||
PAGE_DOWN = (long)Keys.PageDown,
|
||||
F1 = (long)Keys.F1,
|
||||
F2 = (long)Keys.F2,
|
||||
F3 = (long)Keys.F3,
|
||||
F4 = (long)Keys.F4,
|
||||
SHIFT = (long)Keys.Shift,
|
||||
ARROW_LEFT = (long)Keys.Left,
|
||||
ARROW_RIGHT = (long)Keys.Right,
|
||||
ARROW_DOWN = (long)Keys.Down,
|
||||
ARROW_UP = (long)Keys.Up
|
||||
});
|
||||
}
|
||||
|
||||
private void RenderingCanvas_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
DispEngine.KeyUp((long)e.KeyData);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Touch_Events
|
||||
private void RenderingCanvas_GotFocus(object sender, EventArgs e)
|
||||
{
|
||||
// Ensure touch input is enabled when control gets focus
|
||||
this.Capture = true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user