SDD(Sleep-Driven Development)

睡眠の重要性!!睡眠の重要性!!

Visual Studio for Mac Extensionで独自Padを作る

Visual Studio for Macでの独自Padの実装方法です。 ちなみにPadは以下のようなやつです。間違ってたらごめんなさい。

f:id:crocus7724:20170520015028p:plain

今回はサンプルとしてビルドした回数とデバッグした回数を記録しておくPadを作ります。
(本当はRunした回数を取りたかったけど取得の仕方がわからなかった・・・)

PadContentの作成

まず最初にPadContentを継承したクラスを作成します。これはiOS/AndroidでいうUIViewController/Activityみたいな役割で、表示するViewを組み立てたりします。たぶん

実際にコードを見てみましょう。

using System;
using Gtk;
using MonoDevelop.Components;
using MonoDevelop.Debugger;
using MonoDevelop.Ide;
using MonoDevelop.Ide.Gui;
using MonoDevelop.Projects;

namespace SamplePadExtension
{
    /// <summary>
    /// ビルドした回数とデバッグ実行した回数を表示するPad
    /// </summary>
    public class SamplePadExtensionPad : PadContent
    {
        // デバッグした回数
        private int debugCount;

        // ビルドした回数
        private int buildCount;

        // デバッグした回数を表示するラベル
        private Label debugCountLabel;

        // ビルドした回数を表示するラベル
        private Label buildCountLabel;

        // 実際に表示するものを指定するバッキングフィールド
        // overrideのControlプロパティがget onlyなので
        private Control control;

        /// <summary>
        /// 実際に表示するControl(View)を格納するプロパティ
        /// </summary>
        public override Control Control => control;

        /// <summary>
        /// 実際に表示されるときに呼ばれる?
        /// </summary>
        /// <param name="window">Padのウィンドウ. Toolbarとかとれる</param>
        protected override void Initialize(IPadWindow window)
        {
            buildCountLabel = new Label {Text = $"Build count: {buildCount}"};
            debugCountLabel = new Label {Text = $"Debug count: {debugCount}"};

            // 縦積みするレイアウト
            var vBox = new VBox {buildCountLabel, debugCountLabel};
            // 表示
            vBox.ShowAll();
            control = vBox;

            IdeApp.ProjectOperations.StartBuild += OnStartBuild;
            DebuggingService.DebugSessionStarted += OnDebugSessionStarted;
        }

        // ビルドが始まったときに呼ばれる
        private void OnStartBuild(object sender, BuildEventArgs args)
            => buildCountLabel.Text = $"Build count: {++buildCount}";

        // デバッグ実行が始まったときに呼ばれる
        private void OnDebugSessionStarted(object sender, EventArgs eventArgs)
            => debugCountLabel.Text = $"Debug count: {++debugCount}";

        public override void Dispose()
        {
            IdeApp.ProjectOperations.StartBuild -= OnStartBuild;
            DebuggingService.DebugSessionStarted -= OnDebugSessionStarted;

            base.Dispose();
        }
    }
}

注意点なのですが、デバッグの開始を取得するためにMonodevelop.Debuggerを使っています。
デフォルトだと参照できないのでVisual Studio for Mac ExtensionプロジェクトのAddin Reference(下の画像の赤枠のやつ)をダブルクリックして表示されるポップアップからMonodevelop.Debuggerを選択してください。

f:id:crocus7724:20170520020303p:plain

Manifest.addin.xmlの編集

次に上で書いたPadContentを継承したクラスをVisual Studio for Mac Extensionが認識できるようにします。 Propertiesフォルダの中にあるManifest.addin.xmlファイルを以下のように編集します。

<?xml version="1.0" encoding="UTF-8"?>
<ExtensionModel>
    <!-- MainMenu→View→PadsにPadを追加する -->
    <Extension path="/MonoDevelop/Ide/Pads">
        <!-- 実際に追加するPad -->
        <!-- idは固有識別子 -->
        <!-- defaultPlacementは表示させたときのデフォルトの位置 -->
        <!-- classはPadContentを継承したクラスの完全修飾名 -->
        <!-- _labelはPadsに追加されたときに表示される文字 -->
        <Pad id="SamplePadExtension.SamplePadExtensionPad"
             defaultPlacement="Bottom"
             class="SamplePadExtension.SamplePadExtensionPad"
             _label="Sample Extension Pad"/>
    </Extension>
</ExtensionModel>

これで準備は完了です!

実行

それでは実際に実行してみましょう。

f:id:crocus7724:20170520021013p:plain

実行すると上のようなのが追加されていて、ビルドしたりデバッグしたりすると下のようにカウントが増えていくはずです。

f:id:crocus7724:20170520021057p:plain

Xamarin StudioまではファイルテンプレートにGtkがあったのですが、VS for MacからGtkテンプレートが消失してしまい、Xamarin StudioはVS for Macに置き換わる予定ですからGtkファイル手作業作成しか残されてないかなーと思うのですが辛すぎるので手抜きViewです。
もし凝ったレイアウトを作成したい場合は覚悟してください私はやりたくない

もうちょっと詳しく

もう少し凝ったレイアウトやよくあるリスト形式のPadを作成したい場合はおそらくBreakpointのPad実装である

monodevelop/BreakpointPad.cs at master · mono/monodevelop · GitHub

が参考になると思います。

まとめ

Visual Studio for Mac ExtensionならPadの作成も見た目を気にしなくていいならとても簡単にできます。
Padが作成できるとやれることの幅が広がるのでぜひ作ってみてください。