c#-GTK3–DrawingArea-sample

了解です!GTK3 + C#(GtkSharp)を使って、インタラクティブなキャンバス(Gtk.DrawingArea にマウス・キーボード入力を対応させたサンプルコードを用意しました。以下では:


目次

✅ サンプル機能

  • マウスクリック:位置に円を描画
  • マウスドラッグ:線を描画
  • キーボード押下:「C」キーでキャンバスクリア

🎯 C# (GtkSharp) サンプルコード(GTK3)

using Gtk;
using Cairo;
using Gdk;
using System.Collections.Generic;

public class InteractiveCanvas : Window
{
    DrawingArea canvas;
    List<(double x, double y)> circles = new List<(double, double)>();
    List<(double x1, double y1, double x2, double y2)> lines = new List<(double, double, double, double)>();

    double lastX, lastY;
    bool isDragging = false;

    public InteractiveCanvas() : base("Interactive Canvas - GTK3")
    {
        SetDefaultSize(600, 400);
        SetPosition(WindowPosition.Center);

        canvas = new DrawingArea();
        Add(canvas);

        canvas.AddEvents((int)(
            EventMask.ButtonPressMask |
            EventMask.ButtonReleaseMask |
            EventMask.PointerMotionMask |
            EventMask.KeyPressMask
        ));

        canvas.Drawn += OnDraw;
        canvas.ButtonPressEvent += OnMouseDown;
        canvas.ButtonReleaseEvent += OnMouseUp;
        canvas.MotionNotifyEvent += OnMouseMove;

        // キーボード入力を受け取るためのフォーカス設定
        canvas.CanFocus = true;
        canvas.GrabFocus();
        canvas.KeyPressEvent += OnKeyPress;

        DeleteEvent += (o, args) => Application.Quit();
        ShowAll();
    }

    void OnDraw(object sender, DrawnArgs args)
    {
        var cr = args.Cr;

        // 背景
        cr.SetSourceRGB(1, 1, 1);
        cr.Paint();

        // 円を描画
        cr.SetSourceRGB(0.1, 0.6, 1);
        foreach (var (x, y) in circles)
        {
            cr.Arc(x, y, 10, 0, 2 * System.Math.PI);
            cr.Fill();
        }

        // 線を描画
        cr.SetSourceRGB(0, 0, 0);
        cr.LineWidth = 2;
        foreach (var (x1, y1, x2, y2) in lines)
        {
            cr.MoveTo(x1, y1);
            cr.LineTo(x2, y2);
            cr.Stroke();
        }
    }

    void OnMouseDown(object o, ButtonPressEventArgs args)
    {
        double x = args.Event.X;
        double y = args.Event.Y;

        if (args.Event.Button == 1) // 左クリック
        {
            circles.Add((x, y));
            lastX = x;
            lastY = y;
            isDragging = true;
            canvas.QueueDraw();
        }
    }

    void OnMouseUp(object o, ButtonReleaseEventArgs args)
    {
        isDragging = false;
    }

    void OnMouseMove(object o, MotionNotifyEventArgs args)
    {
        if (isDragging)
        {
            double x = args.Event.X;
            double y = args.Event.Y;
            lines.Add((lastX, lastY, x, y));
            lastX = x;
            lastY = y;
            canvas.QueueDraw();
        }
    }

    void OnKeyPress(object o, KeyPressEventArgs args)
    {
        if (args.Event.Key == Gdk.Key.c || args.Event.Key == Gdk.Key.C)
        {
            // 「C」キーでクリア
            circles.Clear();
            lines.Clear();
            canvas.QueueDraw();
        }
    }

    public static void Main()
    {
        Application.Init();
        new InteractiveCanvas();
        Application.Run();
    }
}

📦 ビルド方法(Linux + MonoDevelop or CLI)

1. 依存パッケージのインストール(Ubuntuなどの場合):

sudo apt install gtk-sharp2

2. コンパイル方法(Mono使用時):

mcs -pkg:gtk-sharp-2.0 interactive_canvas.cs -out:interactive_canvas.exe
mono interactive_canvas.exe

💡 ポイント

入力処理内容
マウス左クリック円を追加
マウスドラッグ線を引く
キー「C」キャンバスをクリア

必要に応じて、画像の貼り付けやズームなども追加できます!
ほかにもやりたい操作(拡大縮小・選択ツールなど)ありますか?拡張していくのもアリです!

よかったらシェアしてね!
目次