import { CursorController } from "./CursorController" ; import { Fraction , Point , Vector } from "bp/math" ; import { Device } from "bp/design" ; import type { Studio } from "bp/env" ; import type { Draggable } from "bp/design/class" ; /**
 *  DragController 負責管理使用者拖曳  Control 的行為。
  @ shrewd export class DragController { private _studio : Studio ; /** 目前是否正在進行拖曳。 */ @ shrewd public $on = false ; constructor ( studio ) { this . _studio = studio ; document . addEventListener ( "mouseup" , this . _dragEnd . bind ( this ) , { passive : true } ) ; document . addEventListener ( "touchend" , this . _dragEnd . bind ( this ) , { passive : true } ) ; } private get _draggable ( ) : Draggable [ ] { return this . _studio . $system . $selection . $draggable ; } public $processKey ( key ) { let v = new Vector ( 0 , 0 ) ; switch ( key ) { case "up" : v . set ( 0 , 1 ) ; break ; case "down" : v . set ( 0 , - 1 ) ; break ; case "left" : v . set ( - 1 , 0 ) ; break ; case "right" : v . set ( 1 , 0 ) ; break ; default : return true ; } let selections = this . _draggable ; if ( selections . length == 0 ) return true ; if ( selections [ 0 ] instanceof Device ) v = v . $scale ( Fraction . TWO ) ; for ( let o of selections ) v = o . $dragConstraint ( v ) ; for ( let o of selections ) o . $drag ( v ) ; return false ; } /** 點擊時進行拖曳初始化 */ public $init ( event ) { let selections = this . _draggable ; if ( selections . length ) { CursorController . $tryUpdate ( new Point ( event . downPoint ) . $round ( ) ) ; for ( let o of selections ) o . $dragStart ( CursorController . $offset ) ; this . $on = true ; } } /**
     * 處理拖曳並且傳回是否真的有拖曳發生。
     *
     * 拖曳行為因為是離散的，永遠只能跟拖曳初始位置去做比較而不能跟上次游標位置進行比較。
     */ public $process ( event ) { let pt = new Point ( event . point ) . $round ( ) ; if ( ! CursorController . $tryUpdate ( pt ) ) return false ; for ( let o of this . _draggable ) pt = o . $dragConstraint ( pt ) ; for ( let o of this . _draggable ) o . $drag ( pt ) ; this . _studio . $design ! . $dragging = true ; return true ; } /** 結束拖曳 */ private _dragEnd ( ) { this . $on = false ; if ( this . _studio . $design ) this . _studio . $design . $dragging = false ; } }