Repository navigation
Right Pane UI Design
WPF UIを持つプラグインはSRdeckPlugin.Wpfを参照し、IPluginViewProviderを実装します。右ペインは利用者が受信中に繰り返し見る運用画面です。装飾より、状態、設定、結果、診断の順序と更新の安定性を優先します。
public interface IPluginViewProvider
{
FrameworkElement CreateMainView();
FrameworkElement? CreateSettingsView();
}Descriptorには返すビューに対応するMainView/SettingsView能力を設定します。ビューを返さない能力を宣言したり、能力を宣言せずビューを実装したりしないでください。
- ホストの幅は700 px
- ルート要素に固定
Width、MinWidth、MaxWidthを設定しない - 高さはホストへ追従し、必要な領域だけスクロール
- 横方向へ溢れるDataGridは列の優先度を設計
- 頻繁に更新される値で全体の大きさを変えない
- 低頻度設定をメイン結果領域へ詰め込まない
- ホストのテーマ、フォント、余白、状態色を使用
700 pxで収まることだけでなく、Windows表示スケール125/150%、長い日本語/英語ラベル、空状態、最大値を確認します。
- ヘッダー: プラグイン名と短い状態
-
受信設定: 周波数、プロファイル、チャネル、音声など高頻度設定 -
プラグイン設定: 保持件数、リセット、IQキャプチャなど低頻度設定
外枠はPluginSettingsPanelStyle、ヘッダーはPluginSettingsHeaderStyleを使います。単一ページはPluginSettingsBodyStyle、複数ページはPluginSettingsTabControlStyleを使います。
多くのデジタル方式では次の順序が有効です。
- 状態ヘッダー
概要一覧時系列地図診断
すべての方式へ不要なタブを強制しません。Analogのように結果一覧を持たない方式は概要と診断だけで構いません。
概要は数秒で「動いているか」を判断できる量に絞ります。
- 対象数
- 有効フレーム累計
- 合格率
- 最終受信
- 最近の対象
- 1行の推奨/状態
メトリックカードを増やしすぎず、方式固有の重要指標を4~6個程度に整理します。累計、直近、毎秒をラベルで区別してください。
DataGridの各行にすべてのフィールドを置かず、識別、最新時刻、主状態を表示し、選択詳細ペインへ残りを出します。
- 検索と件数を一覧上部へ置く
- 時刻列の書式を揃える
- 識別子と表示名を区別
- ソート時に更新が選択を飛ばさない
- 空状態を中央に明示
- 詳細ペインは未選択時の案内を持つ
- Raw HEXは折り返し可能なExpanderへ置く
横スクロールを前提にせず、重要度の低い列を詳細へ移します。
時系列は個々のイベントを監査できる画面です。
- 受信時刻
- 対象/チャネル
- 種別
- 検証状態
- 解析済み概要
- 生フレームまたはPayload
- 選択イベントの詳細
一覧の「最新状態」と時系列の「そのフレームが含む値」を混同しないラベルにします。
診断は結果0件のときにも価値がある必要があります。処理順に分けます。
- リアルタイム処理
- 入力・選局
- 信号・チャネル
- 検出・同期・復調
- 検証・復号
- 詳細・デバッグ
各段階に件数、レート、最終状態、失敗理由を表示します。「受信できません」だけで終わらず、どこまで到達したかを示します。内部実装名だけでなく、利用者が次に確認できる説明を添えます。
代表的なリソース:
-
PluginButtonStyle、PluginToggleButtonStyle -
PluginComboBoxStyle、PluginTextBoxStyle -
PluginCheckBoxStyle、PluginRadioButtonStyle、PluginSliderStyle PluginTabControlStyle-
PluginDataGridStyle、PluginTimelineDataGridStyle PluginMetricCardStylePluginStatusHeaderStylePluginDiagnosticsSectionStylePluginResetViewSelectionDetailPane
独自コントロールを作る前に、WPFパッケージのThemesとControlsを検索します。
色をハードコードせず、DynamicResourceを使います。
表示階層:
PluginDisplayAccentPrimaryBrushPluginDisplayAccentSecondaryBrushPluginDisplayAccentTertiaryBrush
動作状態:
PluginStatusRunning...Brush-
Success、Info、Warning、Error、Critical
通常の面と文字:
-
TextPrimaryBrush、TextSecondaryBrush、TextDimBrush PanelSurfaceBrushControlBorderBrush
アクセント色を警告の代用にせず、状態色をカテゴリ分けへ流用しません。色だけで状態を伝えず、ラベル、値、アイコンを併用します。
<Button Content="適用"
Style="{DynamicResource PluginButtonStyle}" />
<TextBlock Text="受信状態"
Foreground="{DynamicResource PluginDisplayAccentPrimaryBrush}" />- 二値設定: CheckBoxまたはToggleButton
- 排他的な少数選択: RadioButton
- 選択肢が多い: ComboBox
- 連続値: Sliderと数値表示
- 正確な数値: TextBox、範囲検証、単位
- 即時コマンド: Button
- 長時間処理: 実行中状態、二重実行防止、完了/失敗表示
単位をラベルか値に含めます。範囲外入力は設定型のNormalizeでも防御し、UI検証だけに依存しません。
- Tab順序が視覚順序と一致
- フォーカス表示を消さない
- ラベルと入力の関連を明確にする
- ToolTipだけへ必須情報を置かない
- AutomationProperties.Nameを必要に応じて設定
- 色以外でも成功/警告/エラーを識別
- 高DPIとキーボードだけで操作確認
- DataGrid選択、スクロール、Expanderへ到達可能
WPFオブジェクトはDispatcherスレッドで操作します。IQコールバックから直接ViewModelコレクションを更新しません。
推奨パターン:
- DSPスレッドで不変スナップショットを作る
- UI更新を一定間隔へ間引く
- Dispatcherへ1回で渡す
- ObservableCollectionを差分更新する
- Stop/Dispose時にTimerと購読を解除する
毎フレームPropertyChangedを大量発火したり、タブ全体を作り直したりすると、WPFが復調処理を圧迫します。
最低限次を設計します。
- 未初期化
- 待機中
- 受信中
- 信号なし
- 結果なし
- 設定拒否
- 同調失敗
- エクスポート中/完了/失敗
- 停止中
- 破棄済み
空のDataGridだけを見せず、「何がまだないか」を表示します。エラーは操作可能な次の手順を示し、詳細例外はログ/診断へ分離します。
- 700 pxと高DPIで切れない
- 設定と結果の境界が分かる
- 概要だけで受信状態を判断できる
- 一覧と時系列の意味が重複していない
- 診断が処理順になっている
- 長い識別子、最大値、空値で崩れない
- テーマ色をハードコードしていない
- キーボードで全操作へ到達できる
- UIを閉じてもDSPが動く
- 高頻度更新で
WPFやPRCを悪化させない - Stop/MODE切替後にTimerやイベントが残らない
詳細な規範は右ペインUIデザイン指針を参照してください。