Index: trunk/parsers/wikidom/lib/hype/views/es.SurfaceView.js |
— | — | @@ -14,14 +14,23 @@ |
15 | 15 | // Initialize document view |
16 | 16 | this.documentView = new es.DocumentView( this.model.getDocument(), this ); |
17 | 17 | this.$.append( this.documentView.$ ); |
18 | | - |
| 18 | + |
| 19 | + // Interaction state |
| 20 | + this.mouse = { |
| 21 | + selecting: false, |
| 22 | + clicks: 0, |
| 23 | + clickDelay: 500, |
| 24 | + clickTimeout: null, |
| 25 | + clickPosition: null, |
| 26 | + hotSpotRadius: 1, |
| 27 | + lastMovePosition: null |
| 28 | + }; |
19 | 29 | this.cursor = { |
20 | 30 | $: $( '<div class="es-surfaceView-cursor"></div>' ).appendTo( this.$ ), |
21 | 31 | interval: null, |
22 | 32 | offset: null, |
23 | 33 | initialLeft: null |
24 | 34 | }; |
25 | | - |
26 | 35 | this.keyboard = { |
27 | 36 | selecting: false, |
28 | 37 | cursorAnchor: null, |
— | — | @@ -32,10 +41,14 @@ |
33 | 42 | command: false, |
34 | 43 | alt: false |
35 | 44 | } |
36 | | - }; |
37 | | - |
| 45 | + }; |
| 46 | + this.selection = { |
| 47 | + from: 0, |
| 48 | + to: 0 |
| 49 | + }; |
| 50 | + |
38 | 51 | // References for use in closures |
39 | | - var surfaceView = this, |
| 52 | + var surfaceView = this, |
40 | 53 | $document = $( document ); |
41 | 54 | |
42 | 55 | // MouseDown on surface |
— | — | @@ -76,6 +89,27 @@ |
77 | 90 | |
78 | 91 | // First render |
79 | 92 | this.documentView.renderContent(); |
| 93 | + |
| 94 | + this.dimensions = { |
| 95 | + width: this.$.width(), |
| 96 | + height: this.$window.height(), |
| 97 | + scrollTop: this.$window.scrollTop() |
| 98 | + }; |
| 99 | + |
| 100 | + // Re-render when resizing horizontally |
| 101 | + this.$window.resize( function() { |
| 102 | + surfaceView.hideCursor(); |
| 103 | + surfaceView.dimensions.height = surfaceView.$window.height(); |
| 104 | + var width = surfaceView.$.width(); |
| 105 | + if ( surfaceView.dimensions.width !== width ) { |
| 106 | + surfaceView.dimensions.width = width; |
| 107 | + surfaceView.documentView.renderContent(); |
| 108 | + } |
| 109 | + } ); |
| 110 | + |
| 111 | + this.$window.scroll( function() { |
| 112 | + surfaceView.dimensions.scrollTop = surfaceView.$window.scrollTop(); |
| 113 | + } ); |
80 | 114 | }; |
81 | 115 | |
82 | 116 | es.SurfaceView.boundaryTest = /([ \-\t\r\n\f])/; |
— | — | @@ -142,7 +176,26 @@ |
143 | 177 | }; |
144 | 178 | |
145 | 179 | es.SurfaceView.prototype.onKeyUp = function( e ) { |
146 | | - // |
| 180 | + switch ( e.keyCode ) { |
| 181 | + case 16: // Shift |
| 182 | + this.keyboard.keys.shift = false; |
| 183 | + if ( this.keyboard.selecting ) { |
| 184 | + this.keyboard.selecting = false; |
| 185 | + } |
| 186 | + break; |
| 187 | + case 17: // Control |
| 188 | + this.keyboard.keys.control = false; |
| 189 | + break; |
| 190 | + case 18: // Alt |
| 191 | + this.keyboard.keys.alt = false; |
| 192 | + break; |
| 193 | + case 91: // Command |
| 194 | + this.keyboard.keys.command = false; |
| 195 | + break; |
| 196 | + default: |
| 197 | + break; |
| 198 | + } |
| 199 | + return true; |
147 | 200 | }; |
148 | 201 | |
149 | 202 | es.SurfaceView.prototype.moveCursor = function( instruction ) { |
— | — | @@ -157,16 +210,29 @@ |
158 | 211 | } else if ( instruction === 'up' || instruction === 'down' ) { |
159 | 212 | // ... |
160 | 213 | } else if ( instruction === 'home' ) { |
161 | | - this.showCursor( this.documentView.getRenderedLineRange( this.cursor.offset ).start ); |
| 214 | + if ( wasLeftBias ) { |
| 215 | + this.showCursor( |
| 216 | + this.documentView.getRenderedLineRangeFromOffset( |
| 217 | + this.documentView.getModel().getRelativeContentOffset( this.cursor.offset, -1 ) |
| 218 | + ).start |
| 219 | + ); |
| 220 | + } else { |
| 221 | + this.showCursor( this.documentView.getRenderedLineRangeFromOffset( this.cursor.offset ).start ); |
| 222 | + } |
162 | 223 | } else if ( instruction === 'end' ) { |
163 | | - var end = this.documentView.getRenderedLineRange( this.cursor.offset ).end; |
164 | | - var data = this.documentView.getModel().data; |
165 | | - if ( es.DocumentModel.isContentData( data, end ) ) { |
166 | | - while ( es.SurfaceView.boundaryTest.exec( data[ end - 1 ] ) ) { |
167 | | - end--; |
168 | | - } |
| 224 | + if ( !wasLeftBias ) { |
| 225 | + this.showCursor( |
| 226 | + this.documentView.getRenderedLineRangeFromOffset( this.cursor.offset ).end, |
| 227 | + true |
| 228 | + ); |
| 229 | + } else { |
| 230 | + this.showCursor( |
| 231 | + this.documentView.getRenderedLineRangeFromOffset( |
| 232 | + this.documentView.getModel().getRelativeContentOffset( this.cursor.offset, -1 ) |
| 233 | + ).end, |
| 234 | + true |
| 235 | + ); |
169 | 236 | } |
170 | | - this.showCursor( end ); |
171 | 237 | } |
172 | 238 | }; |
173 | 239 | |
— | — | @@ -176,8 +242,15 @@ |
177 | 243 | * @method |
178 | 244 | * @param offset {Integer} Position to show the cursor at |
179 | 245 | */ |
180 | | -es.SurfaceView.prototype.showCursor = function( offset, leftBias ) { |
| 246 | +var wasLeftBias = false; |
| 247 | +es.SurfaceView.prototype.showCursor = function( offset, leftBias ) { |
181 | 248 | if ( typeof offset !== 'undefined' ) { |
| 249 | + if ( leftBias ) { |
| 250 | + wasLeftBias = true; |
| 251 | + } else { |
| 252 | + wasLeftBias = false; |
| 253 | + } |
| 254 | + console.log('showCursor: ' + offset + ' leftBias: ' + leftBias); |
182 | 255 | this.cursor.offset = offset; |
183 | 256 | var position = this.documentView.getRenderedPositionFromOffset( |
184 | 257 | this.cursor.offset, leftBias |