135 lines
4.2 KiB
C#
135 lines
4.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
|
|
namespace VisionCommonUI.UserGuide {
|
|
public class GuideManager {
|
|
private readonly List<GuideStep> _steps = new List<GuideStep>();
|
|
private readonly UserControl _baseControl;
|
|
private int _currentStep;
|
|
private GuideOverlayWindow _overlay;
|
|
|
|
public GuideManager(UserControl baseControl) {
|
|
_baseControl = baseControl ?? throw new ArgumentNullException(nameof(baseControl));
|
|
}
|
|
|
|
public void AddStep(
|
|
UIElement target,
|
|
string message,
|
|
string imagePath = null,
|
|
MessagePlacement placement = MessagePlacement.Below,
|
|
double fontSize = 16) {
|
|
if (target == null || !_baseControl.IsLoaded) {
|
|
return;
|
|
}
|
|
|
|
// 위치 계산
|
|
try {
|
|
var transform = target.TransformToAncestor(_baseControl);
|
|
var position = transform.Transform(new Point(0, 0));
|
|
var size = target.RenderSize;
|
|
|
|
if (size.Width <= 0 || size.Height <= 0) {
|
|
return; // 렌더링되지 않은 컨트롤 제외
|
|
}
|
|
|
|
|
|
var imageSource = string.IsNullOrEmpty(imagePath)
|
|
? null
|
|
: LoadPackImage(imagePath);
|
|
|
|
_steps.Add(new GuideStep {
|
|
HighlightArea = new Rect(position, size),
|
|
Message = message,
|
|
Placement = placement,
|
|
FontSize = fontSize,
|
|
Imagesc = imageSource
|
|
});
|
|
}
|
|
catch (Exception ex) {
|
|
Debug.WriteLine($"❌ GuideManager AddStep 오류: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public void Start() {
|
|
if (_steps.Count == 0 || _baseControl == null) {
|
|
return;
|
|
}
|
|
|
|
_overlay = new GuideOverlayWindow {
|
|
WindowStartupLocation = WindowStartupLocation.Manual,
|
|
Owner = Application.Current.MainWindow,
|
|
Width = _baseControl.ActualWidth,
|
|
Height = _baseControl.ActualHeight
|
|
};
|
|
|
|
var topLeft = GetWpfRelativeScreenPosition(_baseControl);
|
|
_overlay.Left = topLeft.X;
|
|
_overlay.Top = topLeft.Y;
|
|
|
|
_overlay.OnNextClicked += Next;
|
|
_overlay.OnPrevClicked += Previous;
|
|
_overlay.OnExitClicked += Exit;
|
|
|
|
_overlay.Show();
|
|
ShowStep(0);
|
|
}
|
|
|
|
private Point GetWpfRelativeScreenPosition(Visual visual) {
|
|
var point = visual.PointToScreen(new Point(0, 0));
|
|
var source = PresentationSource.FromVisual(visual);
|
|
if (source?.CompositionTarget == null) {
|
|
return new Point(0, 0);
|
|
}
|
|
Matrix transform = source.CompositionTarget.TransformFromDevice;
|
|
return transform.Transform(point);
|
|
}
|
|
|
|
private static ImageSource LoadPackImage(string relativePath) {
|
|
try {
|
|
var uri = new Uri($"pack://application:,,,/VisionCommonUI;component/UserGuide/ImgSource/{relativePath}", UriKind.Absolute);
|
|
return new BitmapImage(uri);
|
|
}
|
|
catch (Exception ex) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void ShowStep(int index) {
|
|
if (_overlay == null || index >= _steps.Count) {
|
|
return;
|
|
}
|
|
_currentStep = index;
|
|
_overlay.Highlight(_steps[index]);
|
|
}
|
|
|
|
private void Next() {
|
|
_currentStep++;
|
|
if (_currentStep < _steps.Count) {
|
|
ShowStep(_currentStep);
|
|
}
|
|
else {
|
|
Exit();
|
|
}
|
|
}
|
|
|
|
private void Previous() {
|
|
if (_currentStep > 0) {
|
|
ShowStep(--_currentStep);
|
|
}
|
|
|
|
}
|
|
|
|
private void Exit() {
|
|
if (_overlay == null || _overlay.IsClosing) {
|
|
return;
|
|
}
|
|
_overlay.Close();
|
|
}
|
|
}
|
|
}
|