summaryrefslogtreecommitdiff
path: root/js/ui/selection.js
blob: a2720cb7c75a9a4df2aabc655701718b2f210e3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
var selection = (function(){

  var creating = false, moving = false, copying = false
  
  var selection_canvas = new Matrix (1, 1, function(x,y){
    var lex = new Lex (x,y)
    lex.build()
    return lex
  })
  
  var selector_el = document.createElement("div")
  selector_el.className = "selector_el"
  selection_canvas.append(selector_el)
  document.body.appendChild(selector_el)

  // in selection mode..
  // - we start by clicking the canvas. this positions the selection, and copies
  //   the character
  // - then we drag down and to the right. this resizes the selection and pushes new
  //   rows and columns. each of these copies the character underneath.
  // - on mouseup, the selection is locked. then..
  // - drag the selection to move it -- this "cuts" it and leaves a blank space on the canvas.
  // - shift-drag the selection to copy it
  
  var a = [0, 0]
  var b = [0, 0]
  var c = [0, 0]
  var d = [0, 0]
  
  function reset () {
    a[0] = a[1] = b[0] = b[1] = 0
  }
  function left (a,b) { return min(a[0],b[0]) }
  function top (a,b) { return min(a[1],b[1]) }
  function right (a,b) { return max(a[0],b[0]) }
  function bottom (a,b) { return max(a[1],b[1]) }
  function width (a,b) { return abs(a[0]-b[0])+1 }
  function height (a,b) { return abs(a[1]-b[1])+1 }
  function mag_x (a,b) { return a[0]-b[0] }
  function mag_y (a,b) { return a[1]-b[1] }
  function orient (a,b) {
    var l = left(a,b), m = top(a,b), n = right(a,b), o = bottom(a,b)
    a[0] = l ; a[1] = m ; b[0] = n ; b[1] = o
  }
  
  function contains (a,b,point) {
    var contains_x = a[0] <= point[0] && point[0] <= b[0]
    var contains_y = a[1] <= point[1] && point[1] <= b[1]
    return (contains_x && contains_y)
  }
  function reposition (aa, bb) {
    aa = aa || a
    bb = bb || b
    var cell = canvas.aa[top(aa, bb)][left(aa, bb)].span
    var cell_left = cell.offsetLeft
    var cell_top = cell.offsetTop
    var cell_width = cell.offsetWidth
    var cell_height = cell.offsetHeight

    var w = width(aa, bb)
    var h = height(aa, bb)

    selector_el.style.top = (cell_top-1) + "px"
    selector_el.style.left = (cell_left-1) + "px"
    selector_el.style.width = (cell_width*w+1) + "px"
    selector_el.style.height = (cell_height*h+1) + "px"
  }
  function down (e, lex, point){
    if ( ! contains(a,b,point) ) {
      copying = false
      moving = false
      creating = true
      a[0] = point[0]
      a[1] = point[1]
      b[0] = point[0]
      b[1] = point[1]
      reposition(a,b)
      selection.hidden = false
      selector_el.classList.add("creating")
    } else {
      copying = false
      moving = true
      creating = false
      c[0] = point[0]
      c[1] = point[1]
      d[0] = point[0]
      d[1] = point[1]
    }
    show()
    selector_el.classList.remove("dragging")
  }
  function move (e, lex, point){
    if (creating) {
      b[0] = point[0]
      b[1] = point[1]
      reposition(a,b)
    }
    else if (moving) {
      d[0] = point[0]
      d[1] = point[1]
      var dx = - clamp( mag_x(c,d), b[0] - canvas.w + 1, a[0] )
      var dy = - clamp( mag_y(c,d), b[1] - canvas.h + 1, a[1] )
      reposition( [ a[0] + dx, a[1] + dy ], [ b[0] + dx, b[1] + dy ])
    }
    else if (copying) {
    }
  }
  function up (e) {
    if (creating) {
      orient(a,b)
      selection_canvas.resize(width(a,b), height(a,b))
      reposition(a,b)
      blit.copy_from( canvas, selection_canvas, a[0], a[1] )
      selection_canvas.build()
      selector_el.classList.remove("creating")
    }
    if (moving) {
      var dx = - clamp( mag_x(c,d), b[0] - canvas.w + 1, a[0] )
      var dy = - clamp( mag_y(c,d), b[1] - canvas.h + 1, a[1] )
      a[0] += dx
      a[1] += dy
      b[0] += dx
      b[1] += dy
      undo.new()
      undo.save_rect(a[0], a[1], b[0] - a[0] + 1, b[1] - a[1] + 1)
      blit.copy_to( canvas, selection_canvas, a[0], a[1] )
    }
    if (copying) {
    }
    creating = moving = copying = false
    selector_el.classList.remove("dragging")
  }
  
  function show () {
    selecting = true
  }
  function hide () {
    reset()
    selector_el.style.top = "-9999px"
    selector_el.style.left = "-9999px"
    selector_el.style.width = "0px"
    selector_el.style.height = "0px"
    creating = moving = copying = false
    selection.hidden = true
    selecting = false
  }
  
  var selection = {}
  selection.reposition = reposition
  selection.down = down
  selection.move = move
  selection.up = up
  selection.canvas = selection_canvas
  selection.show = show
  selection.hide = hide
  selection.hidden = true
  return selection

})()