Files
xyou f70b061d1a
CI / Go Backend (push) Canceled after 0s
feat: 项目初始化 + 3D方块世界原型 + AI助搭系统
初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器

HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块

Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚

AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
2026-08-08 14:07:56 +08:00

323 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace PCL;
public partial class MyExtraButton
{
public delegate void ClickEventHandler(object sender, MouseButtonEventArgs e); // 自定义事件
public delegate void RightClickEventHandler(object sender, MouseButtonEventArgs e);
public delegate bool ShowCheckDelegate();
// 自定义事件
// 务必放在 IsMouseDown 更新之后
private const int animationColorIn = 120;
private const int animationColorOut = 150;
// 鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
private bool isLeftMouseHeld;
private bool isRightMouseHeld;
public ShowCheckDelegate showCheck = null;
// 自定义属性
public int Uuid = ModBase.GetUuid();
public MyExtraButton()
{
Loaded += (_, _) => RefreshColor();
IsEnabledChanged += (_, _) => RefreshColor();
InitializeComponent();
PanClick.MouseLeave += (_, _) => Button_MouseLeave();
}
public double Progress
{
get;
set
{
if (field == value)
return;
field = value;
if (value < 0.0001d)
{
PanProgress.Visibility = Visibility.Collapsed;
}
else
{
PanProgress.Visibility = Visibility.Visible;
RectProgress.Rect = new Rect(0d, 40d * (1d - value), 40d, 40d * value);
}
}
}
public string Logo
{
get;
set
{
if ((value ?? "") == (field ?? ""))
return;
field = value;
Path.Data = (Geometry)new GeometryConverter().ConvertFromString(value);
SvgIconControlHelper.ApplyVisibility(Path, ShapeSvgIcon, IsUsingSvgIcon);
}
} = "";
public string SvgIcon
{
get;
set
{
value ??= string.Empty;
if (value == field)
return;
field = value;
if (Path is null || ShapeSvgIcon is null)
return;
SvgIconControlHelper.ApplyIcon(Path, ShapeSvgIcon, field);
ApplyLogoScale();
}
} = string.Empty;
private bool IsUsingSvgIcon => SvgIconControlHelper.HasSvgIcon(SvgIcon);
private double EffectiveLogoScale => IsUsingSvgIcon ? 1D : LogoScale;
public double LogoScale
{
get;
set
{
field = value;
ApplyLogoScale();
}
} = 1d;
public bool Show
{
get;
set
{
if (field == value)
return;
field = value;
ModBase.RunInUi(() =>
{
if (value)
{
// 有了
Visibility = Visibility.Visible;
ModAnimation.AniStart(
new[]
{
ModAnimation.AaScaleTransform(this, 0.3d - ((ScaleTransform)RenderTransform).ScaleX, 500,
60, new ModAnimation.AniEaseOutFluent(ModAnimation.AniEasePower.Weak)),
ModAnimation.AaScaleTransform(this, 0.7d, 500, 60,
new ModAnimation.AniEaseOutBack(ModAnimation.AniEasePower.Weak)),
ModAnimation.AaHeight(this, 50d - Height, 200,
ease: new ModAnimation.AniEaseOutFluent(ModAnimation.AniEasePower.Weak))
}, "MyExtraButton MainScale " + Uuid);
}
else
{
// 没了
ModAnimation.AniStart(
new[]
{
ModAnimation.AaScaleTransform(this, -((ScaleTransform)RenderTransform).ScaleX, 100,
ease: new ModAnimation.AniEaseInFluent(ModAnimation.AniEasePower.Weak)),
ModAnimation.AaHeight(this, -Height, 400, 100, new ModAnimation.AniEaseOutFluent()),
ModAnimation.AaCode(() => Visibility = Visibility.Collapsed, after: true)
}, "MyExtraButton MainScale " + Uuid);
}
IsHitTestVisible = value; // 防止缩放动画中依然可以点进去
});
}
}
public bool CanRightClick { get; set; }
private void ApplyLogoScale()
{
IconHost?.RenderTransform = new ScaleTransform { ScaleX = EffectiveLogoScale, ScaleY = EffectiveLogoScale };
}
// 声明
public event ClickEventHandler? Click;
public event RightClickEventHandler? RightClick;
private void StartScaleAnimation(double targetScale, double reboundScale, int reboundDuration = 60)
{
ModAnimation.AniStart(
new[]
{
ModAnimation.AaScaleTransform(PanScale, targetScale - ((ScaleTransform)PanScale.RenderTransform).ScaleX,
800, ease: new ModAnimation.AniEaseOutFluent(ModAnimation.AniEasePower.Strong)),
ModAnimation.AaScaleTransform(PanScale, reboundScale, reboundDuration,
ease: new ModAnimation.AniEaseOutFluent())
}, "MyExtraButton Scale " + Uuid);
}
private void RefreshScaleAfterRelease()
{
ModAnimation.AniStart(
new[]
{
ModAnimation.AaScaleTransform(PanScale, 1d - ((ScaleTransform)PanScale.RenderTransform).ScaleX, 300,
ease: new ModAnimation.AniEaseOutBack())
}, "MyExtraButton Scale " + Uuid);
}
public void ShowRefresh()
{
if (showCheck is not null)
Show = showCheck();
}
// 触发点击事件
private void Button_LeftMouseUp(object sender, MouseButtonEventArgs e)
{
if (isLeftMouseHeld)
{
ModBase.Log("[Control] 按下附加按钮" +
(ToolTip is null or "" ? "" : "" + ToolTip));
Click?.Invoke(sender, e);
e.Handled = true;
Button_LeftMouseUp();
}
}
private void Button_RightMouseUp(object sender, MouseButtonEventArgs e)
{
if (isRightMouseHeld)
{
ModBase.Log("[Control] 右键按下附加按钮" +
(ToolTip is null or "" ? "" : "" + ToolTip));
RightClick?.Invoke(sender, e);
e.Handled = true;
Button_RightMouseUp();
}
}
private void Button_LeftMouseDown(object sender, MouseButtonEventArgs e)
{
if (!isLeftMouseHeld && !isRightMouseHeld)
StartScaleAnimation(0.85d, -0.05d);
isLeftMouseHeld = true;
Focus();
}
private void Button_RightMouseDown(object sender, MouseButtonEventArgs e)
{
if (!CanRightClick)
return;
if (!isLeftMouseHeld && !isRightMouseHeld)
StartScaleAnimation(0.85d, -0.05d);
isRightMouseHeld = true;
Focus();
}
private void Button_LeftMouseUp()
{
if (!isRightMouseHeld)
RefreshScaleAfterRelease();
if (isLeftMouseHeld) ModMain.RaiseCustomEvent(this);
isLeftMouseHeld = false;
RefreshColor(); // 直接刷新颜色以判断是否已触发 MouseLeave
}
private void Button_RightMouseUp()
{
if (!CanRightClick)
return;
if (!isLeftMouseHeld)
RefreshScaleAfterRelease();
isRightMouseHeld = false;
RefreshColor(); // 直接刷新颜色以判断是否已触发 MouseLeave
}
private void Button_MouseLeave()
{
isLeftMouseHeld = false;
isRightMouseHeld = false;
ModAnimation.AniStart(
new[]
{
ModAnimation.AaScaleTransform(PanScale, 1d - ((ScaleTransform)PanScale.RenderTransform).ScaleX, 500,
ease: new ModAnimation.AniEaseOutFluent())
}, "MyExtraButton Scale " + Uuid);
RefreshColor(); // 直接刷新颜色以判断是否已触发 MouseLeave
}
public void RefreshColor()
{
try
{
if (ControlVisualHelpers.ShouldAnimate(this)) // 防止默认属性变更触发动画
{
if (!IsEnabled)
// 禁用
ModAnimation.AniStart(
ModAnimation.AaColor(PanColor, BackgroundProperty, "ColorBrushGray4", animationColorIn),
"MyExtraButton Color " + Uuid);
else if (IsMouseOver)
// 指向
ModAnimation.AniStart(
ModAnimation.AaColor(PanColor, BackgroundProperty, "ColorBrush4", animationColorIn),
"MyExtraButton Color " + Uuid);
else
// 普通
ModAnimation.AniStart(
ModAnimation.AaColor(PanColor, BackgroundProperty, "ColorBrush3", animationColorOut),
"MyExtraButton Color " + Uuid);
}
else
{
ControlVisualHelpers.AnimateColorOrSetResource(PanColor, BackgroundProperty,
!IsEnabled ? "ColorBrushGray4" : IsMouseOver ? "ColorBrush4" : "ColorBrush3",
!IsEnabled || IsMouseOver ? animationColorIn : animationColorOut,
"MyExtraButton Color " + Uuid, false);
}
}
catch (Exception ex)
{
ModBase.Log(ex, "刷新图标按钮颜色出错");
}
}
/// <summary>
/// 发出一圈波浪效果提示。
/// </summary>
public void Ribble()
{
ModBase.RunInUi(() =>
{
var shape = new Border
{
CornerRadius = new CornerRadius(1000d), BorderThickness = new Thickness(0.001d), Opacity = 0.5d,
RenderTransformOrigin = new Point(0.5d, 0.5d), RenderTransform = new ScaleTransform()
};
shape.SetResourceReference(Border.BackgroundProperty, "ColorBrush5");
PanScale.Children.Insert(0, shape);
ModAnimation.AniStart(
new[]
{
ModAnimation.AaScaleTransform(shape, 13d, 1000,
ease: new ModAnimation.AniEaseInoutFluent(ModAnimation.AniEasePower.Strong, 0.3d)),
ModAnimation.AaOpacity(shape, -shape.Opacity, 1000),
ModAnimation.AaCode(() => PanScale.Children.Remove(shape), after: true)
}, "ExtraButton Ribble " + ModBase.GetUuid());
});
}
private void PanClick_MouseEvent(object sender, MouseEventArgs e)
{
RefreshColor();
}
}