1 // OpenTween - Client of Twitter
2 // Copyright (c) 2015 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
5 // This file is part of OpenTween.
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
17 // You should have received a copy of the GNU General public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
23 using System.Collections.Generic;
26 using System.Threading.Tasks;
27 using System.Windows.Forms;
31 public enum FocusedControl
40 /// ショートカットキーの条件と動作を定義するクラス
42 public class ShortcutCommand
44 private Keys[] shortcuts;
45 private FocusedControl focusedOn;
46 private FocusedControl notFocusedOn;
47 private Func<bool> onlyWhen;
48 private Func<Task> command;
49 private bool preventDefault;
52 /// ショートカットキーが動作する条件となるキー入力
54 public Keys[] Shortcuts
56 get { return this.shortcuts; }
60 /// ショートカットキーが動作する条件となるフォーカス状態
62 public FocusedControl FocusedOn
64 get { return this.focusedOn; }
68 /// ショートカットキーが動作する否定条件となるフォーカス状態
70 public FocusedControl NotFocusedOn
72 get { return this.notFocusedOn; }
76 /// コマンドを実行した後、コントロール既定の動作を無効化するか否か (デフォルトは true)
78 public bool PreventDefault
80 get { return this.preventDefault; }
83 private ShortcutCommand()
85 this.shortcuts = new Keys[0];
86 this.command = () => Task.FromResult(0);
87 this.onlyWhen = () => true;
88 this.focusedOn = FocusedControl.None;
89 this.notFocusedOn = FocusedControl.None;
90 this.preventDefault = true;
94 /// コマンドを実行する条件を満たしているか判定します
96 public bool IsMatch(Keys pressedKey, FocusedControl focusedOn)
98 if (!this.Shortcuts.Contains(pressedKey))
101 if (this.FocusedOn != FocusedControl.None && this.FocusedOn != focusedOn)
104 if (this.NotFocusedOn != FocusedControl.None && this.NotFocusedOn == focusedOn)
107 if (!this.onlyWhen())
116 public async Task RunCommand()
118 await this.command();
122 /// 新規に ShortcutCommand インスタンスを作成するビルダーを返します
124 public static ShortcutCommand.Builder Create(params Keys[] shortcuts)
126 return new Builder().Keys(shortcuts);
131 private readonly ShortcutCommand instance;
135 this.instance = new ShortcutCommand();
139 /// 指定されたキーが入力された時にショートカットを発動します
141 public Builder Keys(params Keys[] shortcuts)
143 this.instance.shortcuts = shortcuts;
148 /// 指定されたコントロールにフォーカスが当たっている時のみショートカットを有効にします
150 public Builder FocusedOn(FocusedControl focusedOn)
152 this.instance.focusedOn = focusedOn;
157 /// 指定されたコントロールにフォーカスが当たっている時はショートカットを有効にしません
159 public Builder NotFocusedOn(FocusedControl notFocusedOn)
161 this.instance.notFocusedOn = notFocusedOn;
166 /// 指定された条件が true になる間のみショートカットを有効にします
168 public Builder OnlyWhen(Func<bool> condition)
170 this.instance.onlyWhen = condition;
175 /// ショートカットが入力された時に行う動作の内容
177 public ShortcutCommand Do(Action action, bool preventDefault = true)
179 return this.Do(SynchronousTask(action), preventDefault);
183 /// ショートカットが入力された時に行う動作の内容
185 public ShortcutCommand Do(Func<Task> action, bool preventDefault = true)
187 this.instance.command = action;
188 this.instance.preventDefault = preventDefault;
190 return this.instance;
193 /// <summary>何もしないタスク</summary>
194 private static Task noOpTask = Task.FromResult(0);
197 /// Action を Func<Task> に変換します
199 private static Func<Task> SynchronousTask(Action action)
201 return () => { action(); return noOpTask; };