・------------------------------------------------------------------------------------・
・アイコン選択です。
・マウスが移動するとその区域の三角矢印が付き、またアンダーラインがひかれ
・どのアイコンを選択しているかわかる仕組み。よくあるやつです。
・SkiaSharpについては 別記事参照
・------------------------------------------------------------------------------------・
・アイコン選択です。
・マウスが移動するとその区域の三角矢印が付き、またアンダーラインがひかれ
・どのアイコンを選択しているかわかる仕組み。よくあるやつです。
・SkiaSharpについては 別記事参照
・------------------------------------------------------------------------------------・
Inceaceが選択されるている様子
(画像は(c)コンポーネントソース社)
1.解説
丸型の場合はマウスが何処のアイコンを選択しているか判定するにはSin,Cosの三角関数を使用して全区域のXY値を調べる必要があります。
この場合は8アイコンに分かれるのでそれぞれの区画の全XY値を取得。
・格納領域
// XY値格納
struct B1{
public int x,y;
}
static B1[] BT1 = new B1[170000];
・8個の内の一つの区域の全XY値取得
x1,y1は円中心から40離れた所のXY値、更にx1,y1を円中心として円周上までのXY値を取得し構造体に格納。これを全8区画において実施。このサイズの場合はSin,Cosを計34万回計算するが瞬時に終わる。
for (int g=135;g<370;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
下記画像の様にそれぞれのアイコンを選択されている画像を用意し、VSのResourceに入れておく。
(一枚にしておいてアンダーラインと三角矢印を描画する方法もある。その方がスマートではある)
1.png "Resources/1.png" x:Name="AAA"
2.png "Resources/2.png" x:Name="BBB"
XAMLでは、
<Border>
<Image x:Name="AAA" Source="Resources/1.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="BBB" Source="Resources/2.png" Width="263" Height="263" />
</Border>
・マウス移動イベントハンドラでマウスのXY値と先に格納したXY値と照合して該当する「アイコンが選択されている画像」を表示、その他を非表示にする。
private void skiaCanvas_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) {
// ローカルマウス位置
System.Windows.Point point = e.GetPosition(this);
int MY=(int)point.Y;
int MX=(int)point.X;
//1
for (int f=0;f<=20700;f++){
if (MY == BT1[f].y && MX == BT1[f].x ) {
AAA.Visibility=Visibility.Visible;
BBB.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Hidden;
}
}
//2
for (int f=20700;f<=40000;f++){
if (MY == BT1[f].y && MX == BT1[f].x ) {
AAA.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
BBB.Visibility=Visibility.Visible;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Hidden;
}
}
簡単にやるとしたら各アイコンの背景色を変えておいて(RGB値で1違うだけなら見た目わからない)マウスの場所の色を取得して判定する方法もある。こんな事を考えるのは自分位かも知れない。動作に問題なければそれで良いんです。ごまかし万歳です。
2.全ソースコード (WPF C#)
/////////////////////////////////////////////////
// Menu,ランチャ WPF+SkiaSharp / (c)inf102 2023.
/////////////////////////////////////////////////
using SkiaSharp;
using SkiaSharp.Views.Desktop;
using System;
using System.Windows;
namespace WPF_CIRCLE_BTN {
public partial class MainWindow : Window {
public void m(string m){
MessageBox.Show(m);
}
public MainWindow() {
InitializeComponent();
skiaCanvas.InvalidateVisual();
}
// XY値格納
struct B1{
public int x,y;
}
// 表示データ構造体配列
static B1[] BT1 = new B1[170000];
void PaintSurface(object sender, SKPaintSurfaceEventArgs args){
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
SKPaint W_LINE= new SKPaint{
Style = SKPaintStyle.Stroke,
Color = new SKColor(0, 0,0),
IsAntialias=true,
StrokeWidth = 1
};
//////////////////////////////////////////////////
// 冗長コードが続くため、メソッド化してください。
// サンプルでそれをやると分かり辛くなるので止めてます。
double x1,y1,x2,y2;
int cc=0;
// 1
for (int g=135;g<370;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
// 2
for (int g=390;g<618;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
// 3
for (int g=637;g<866;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
// 4
for (int g=886;g<1114;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
// 5
for (int g=1134;g<1363;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
// 6
for (int g=1383;g<1615;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
// 7
for (int g=1630;g<1870;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
// 8
for (int g=1885;g<2120;g++){
x1=info.Width / 2+40*Math.Sin(g*Math.PI/1000);
y1=info.Height / 2-40*Math.Cos(g*Math.PI/1000);
for (int h=1;h<90;h++){
x2=x1+h*Math.Sin(g*Math.PI/1000);
BT1[cc].x=(int)x2;
y2=y1-h*Math.Cos(g*Math.PI/1000);
BT1[cc].y=(int)y2;
cc++;
// canvas.DrawPoint( (int)(x2),(int)y2,W_LINE);
}
}
}
// ここも適当にメソッド化して簡略化してください。
private void skiaCanvas_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) {
// ローカルマウス位置
System.Windows.Point point = e.GetPosition(this);
int MY=(int)point.Y;
int MX=(int)point.X;
//1
for (int f=0;f<=20700;f++){
if (MY == BT1[f].y && MX == BT1[f].x ) {
AAA.Visibility=Visibility.Visible;
BBB.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Hidden;
}
}
//2
for (int f=20700;f<=40000;f++){
if (MY == BT1[f].y && MX == BT1[f].x ) {
AAA.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
BBB.Visibility=Visibility.Visible;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Hidden;
}
}
//3
for (int f=41500;f<=61800;f++){
if (MY == BT1[f].y && MX == BT1[f].x ) {
CCC.Visibility=Visibility.Visible;
AAA.Visibility=Visibility.Hidden;
BBB.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Hidden;
}
}
//4
for (int f=61800;f<=82000;f++){
if (MY == BT1[f].y && MX == BT1[f].x ){
CCC.Visibility=Visibility.Hidden;
AAA.Visibility=Visibility.Hidden;
BBB.Visibility=Visibility.Hidden;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Visible;
GGG.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Hidden;
}
}
//5
for (int f=82100;f<=102500;f++){
if (MY == BT1[f].y && MX == BT1[f].x ){
EEE.Visibility=Visibility.Visible;
BBB.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
AAA.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Hidden;
}
}
//6
for (int f=102700;f<=123000;f++){
if (MY == BT1[f].y && MX == BT1[f].x ){
EEE.Visibility=Visibility.Hidden;
BBB.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
AAA.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Visible;
HHH.Visibility=Visibility.Hidden;
}
}
//7
for (int f=123000;f<=144200;f++){
if (MY == BT1[f].y && MX == BT1[f].x ) {
AAA.Visibility=Visibility.Hidden;
BBB.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Visible;
HHH.Visibility=Visibility.Hidden;
}
}
//8
for (int f=144500;f<=167700;f++){
if (MY == BT1[f].y && MX == BT1[f].x ) {
AAA.Visibility=Visibility.Hidden;
BBB.Visibility=Visibility.Hidden;
CCC.Visibility=Visibility.Hidden;
DDD.Visibility=Visibility.Hidden;
EEE.Visibility=Visibility.Hidden;
FFF.Visibility=Visibility.Hidden;
GGG.Visibility=Visibility.Hidden;
HHH.Visibility=Visibility.Visible;
}
}
}
}
}
3.XAML
<Window x:Class="WPF_CIRCLE_BTN.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_CIRCLE_BTN" xmlns:wpf="clr-namespace:SkiaSharp.Views.WPF;assembly=SkiaSharp.Views.WPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="450" >
<Grid>
<Border>
<Image x:Name="AAA" Source="Resources/1.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="BBB" Source="Resources/2.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="CCC" Source="Resources/3.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="DDD" Source="Resources/4.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="EEE" Source="Resources/5.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="FFF" Source="Resources/6.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="GGG" Source="Resources/7.png" Width="263" Height="263" />
</Border>
<Border>
<Image x:Name="HHH" Source="Resources/8.png" Width="263" Height="263" />
</Border>
<wpf:SKElement x:Name="skiaCanvas" PaintSurface="PaintSurface" MouseMove="skiaCanvas_MouseMove" />
</Grid>
</Window>