/// <summary> /// マウスジェスチャ検出開始 /// </summary> /// <param name="target">マウスジェスチャを動作させるコントロール</param> /// <param name="button">マウスボタン</param> /// <param name="interval">移動方向の検出に必要な距離(画素数)</param> public void Start(Control target, MouseButtons button, int interval) { var move = target.MouseMoveAsObservable(); var up = target.MouseUpAsObservable().Where(e => e.Button == button); this.disposable = target.MouseDownAsObservable().Where(e => e.Button == button) .SelectMany(arg0 => { return move.TakeUntil(up) .Select(arg1 => { //マウスの移動方向を↑,↓,←,→の文字に置き換える var arrow = GetArrowChar(arg1.Location.X - arg0.Location.X, arg1.Location.Y - arg0.Location.Y, interval); if (arrow != char.MinValue) //方向を検知(interval以上移動)した場合 arg0 = arg1; //起点を更新 return arrow; }) .Where(arrow => arrow != char.MinValue) //方向を検知した場合のみ通す .DistinctUntilChanged() //同じ方向を連続して通さない .Take(this.maxCount) //最大数(最長コマンドの長さ)までを取得 .Aggregate(string.Empty, //矢印を連結してstringにする (gesture, arrow) => { OnDirectionCaptured(gesture + arrow); return gesture + arrow; }) .Zip(up, (gesture, _) => gesture); //マウスUpが来るまで待機 }) .Subscribe(gesture => { //ドラッグで取得したジェスチャパターンが存在したら、対応するコマンドを実行 Action command; if (gestures.TryGetValue(gesture, out command)) { command(); OnCommandExcuted(gesture); } }); }
/// <summary> /// マウスイベントの開始 /// </summary> /// <param name="target">イベント発生元コントロール</param> /// <param name="button">ドラッグイベントに対応するマウスボタン</param> public void Start(Control target, MouseButtons button) { IDraggable active = this.DefaultItem; //ボタンが押されていない間のマウスムーブイベント this.Disposables.Add( target.MouseMoveAsObservable() .Where(e => e.Button == MouseButtons.None) .Subscribe( e => { //選択中のオブジェクトを先行してチェック active = SelectedItems.HitTest(e.Location); if (active != null) { target.Cursor = active.Cursor; return; } //カーソルの下にあるm_shapes内のオブジェクトをactiveに設定する。 //オブジェクトのない場所にカーソルがある場合はDefaultItemがActiveとなる。 active = DefaultItem; foreach (IDraggable item in Items.Reverse<IDraggable>()) { var result = item.HitTest(e.Location); if (result != null) { active = result; break; } }; target.Cursor = active.Cursor; })); //マウスダウンイベント this.Disposables.Add( target.MouseDownAsObservable() .Subscribe( e => { var act = active as ISelectable; if (act != null && !act.IsSelected) { foreach (ISelectable item in this.Selectables) { item.IsSelected = item == act; } this.SelectedItems = new CompositeDraggable(Enumerable.Empty<IDraggable>()); target.Refresh(); }; })); //ドラッグイベント this.Disposables.Add( target.MouseDragAsObservable(button) .Subscribe( e => { active.Drag(e); target.Refresh(); })); //マウスアップイベント this.Disposables.Add( target.MouseUpAsObservable() .Subscribe( e => { var item = active.Drop(); if (item != null) this.AddItem(item); target.Refresh(); })); }