mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Selections render themselves on screen (1 div per line)
Still a lot of details to cover, but basic selection creation is working.
This commit is contained in:
@@ -233,8 +233,6 @@ describe "Editor", ->
|
||||
editor.trigger keydownEvent('right', shiftKey: true)
|
||||
|
||||
expect(selection.isEmpty()).toBeFalsy()
|
||||
expect(selection.anchor.getPosition()).toEqual(row: 1, column: 6)
|
||||
expect(selection.cursor.getPosition()).toEqual(row: 1, column: 7)
|
||||
range = selection.getRange()
|
||||
expect(range.start).toEqual(row: 1, column: 6)
|
||||
expect(range.end).toEqual(row: 1, column: 7)
|
||||
|
||||
@@ -10,7 +10,7 @@ describe "Range", ->
|
||||
range2 = new Range(new Point(1, 4), new Point(0, 1))
|
||||
expect(range2.start).toEqual(row: 0, column: 1)
|
||||
|
||||
describe "isEmpty", ->
|
||||
describe ".isEmpty()", ->
|
||||
it "returns true if @start equals @end", ->
|
||||
expect(new Range(new Point(1, 1), new Point(1, 1)).isEmpty()).toBeTruthy()
|
||||
expect(new Range(new Point(1, 1), new Point(1, 2)).isEmpty()).toBeFalsy()
|
||||
|
||||
90
spec/atom/selection-spec.coffee
Normal file
90
spec/atom/selection-spec.coffee
Normal file
@@ -0,0 +1,90 @@
|
||||
Buffer = require 'buffer'
|
||||
Editor = require 'editor'
|
||||
Range = require 'range'
|
||||
|
||||
describe "Selection", ->
|
||||
[editor, buffer, selection] = []
|
||||
|
||||
beforeEach ->
|
||||
buffer = new Buffer(require.resolve('fixtures/sample.js'))
|
||||
editor = Editor.build()
|
||||
editor.enableKeymap()
|
||||
editor.setBuffer(buffer)
|
||||
selection = editor.selection
|
||||
|
||||
describe ".setRange(range)", ->
|
||||
it "places the anchor at the start of the range and the cursor at the end", ->
|
||||
range = new Range({row: 2, column: 7}, {row: 3, column: 18})
|
||||
selection.setRange(range)
|
||||
expect(selection.anchor.getPosition()).toEqual range.start
|
||||
expect(selection.cursor.getPosition()).toEqual range.end
|
||||
|
||||
fdescribe ".updateAppearence()", ->
|
||||
[charWidth, lineHeight] = []
|
||||
|
||||
beforeEach ->
|
||||
editor.attachToDom()
|
||||
{ charWidth, lineHeight } = editor
|
||||
|
||||
describe "when the selection is within a single line", ->
|
||||
it "covers the selection's range with a single region", ->
|
||||
selection.setRange(new Range({row: 2, column: 7}, {row: 2, column: 25}))
|
||||
|
||||
expect(selection.regions.length).toBe 1
|
||||
region = selection.regions[0]
|
||||
expect(region.position().top).toBe(2 * lineHeight)
|
||||
expect(region.position().left).toBe(7 * charWidth)
|
||||
expect(region.height()).toBe lineHeight
|
||||
expect(region.width()).toBe((25 - 7) * charWidth)
|
||||
|
||||
describe "when the selection spans 2 lines", ->
|
||||
it "covers the selection's range with 2 regions", ->
|
||||
selection.setRange(new Range({row: 2, column: 7}, {row: 3, column: 25}))
|
||||
|
||||
expect(selection.regions.length).toBe 2
|
||||
|
||||
region1 = selection.regions[0]
|
||||
expect(region1.position().top).toBe(2 * lineHeight)
|
||||
expect(region1.position().left).toBe(7 * charWidth)
|
||||
expect(region1.height()).toBe lineHeight
|
||||
expect(region1.width()).toBe(editor.width() - region1.position().left)
|
||||
|
||||
region2 = selection.regions[1]
|
||||
expect(region2.position().top).toBe(3 * lineHeight)
|
||||
expect(region2.position().left).toBe(0)
|
||||
expect(region2.height()).toBe lineHeight
|
||||
expect(region2.width()).toBe(25 * charWidth)
|
||||
|
||||
describe "when the selection spans more than 2 lines", ->
|
||||
it "covers the selection's range with a region for each line", ->
|
||||
selection.setRange(new Range({row: 2, column: 7}, {row: 4, column: 25}))
|
||||
|
||||
expect(selection.regions.length).toBe 3
|
||||
|
||||
region1 = selection.regions[0]
|
||||
expect(region1.position().top).toBe(2 * lineHeight)
|
||||
expect(region1.position().left).toBe(7 * charWidth)
|
||||
expect(region1.height()).toBe lineHeight
|
||||
expect(region1.width()).toBe(editor.width() - region1.position().left)
|
||||
|
||||
region2 = selection.regions[1]
|
||||
expect(region2.position().top).toBe(3 * lineHeight)
|
||||
expect(region2.position().left).toBe(0)
|
||||
expect(region2.height()).toBe lineHeight
|
||||
expect(region2.width()).toBe(editor.width())
|
||||
|
||||
region3 = selection.regions[2]
|
||||
expect(region3.position().top).toBe(4 * lineHeight)
|
||||
expect(region3.position().left).toBe(0)
|
||||
expect(region3.height()).toBe lineHeight
|
||||
expect(region3.width()).toBe(25 * charWidth)
|
||||
|
||||
it "clears previously drawn regions before creating new ones", ->
|
||||
selection.setRange(new Range({row: 2, column: 7}, {row: 4, column: 25}))
|
||||
expect(selection.regions.length).toBe 3
|
||||
expect(selection.find('.selection').length).toBe 3
|
||||
|
||||
selection.updateAppearance()
|
||||
expect(selection.regions.length).toBe 3
|
||||
expect(selection.find('.selection').length).toBe 3
|
||||
|
||||
@@ -10,8 +10,8 @@ class Cursor extends Template
|
||||
viewProperties:
|
||||
editor: null
|
||||
|
||||
initialize: (editor) ->
|
||||
@editor = editor
|
||||
initialize: (@selection) ->
|
||||
@editor = @selection.editor
|
||||
|
||||
bufferChanged: (e) ->
|
||||
@setPosition(e.postRange.end)
|
||||
@@ -20,7 +20,7 @@ class Cursor extends Template
|
||||
point = Point.fromObject(point)
|
||||
@point = @editor.clipPosition(point)
|
||||
@goalColumn = null
|
||||
@updateScreenPosition()
|
||||
@selection.updateAppearance()
|
||||
|
||||
getPosition: -> _.clone(@point)
|
||||
|
||||
@@ -81,7 +81,7 @@ class Cursor extends Template
|
||||
|
||||
@setPosition({row, column})
|
||||
|
||||
updateScreenPosition: ->
|
||||
updateAppearance: ->
|
||||
position = @editor.pixelPositionFromPoint(@point)
|
||||
@css(position)
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ class Editor extends Template
|
||||
@charWidth = fragment.width()
|
||||
@lineHeight = fragment.outerHeight()
|
||||
fragment.remove()
|
||||
@selection.updateScreenPosition()
|
||||
@selection.updateAppearance()
|
||||
|
||||
scrollBottom: (newValue) ->
|
||||
if newValue?
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
Point = require 'point'
|
||||
|
||||
module.exports =
|
||||
class Range
|
||||
constructor: (pointA, pointB) ->
|
||||
pointA = Point.fromObject(pointA)
|
||||
pointB = Point.fromObject(pointB)
|
||||
|
||||
if pointA.compare(pointB) <= 0
|
||||
@start = pointA
|
||||
@end = pointB
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
Template = require 'template'
|
||||
Cursor = require 'cursor'
|
||||
Range = require 'range'
|
||||
$$ = require 'template/builder'
|
||||
|
||||
module.exports =
|
||||
class Selection extends Template
|
||||
@@ -8,15 +9,59 @@ class Selection extends Template
|
||||
@div()
|
||||
|
||||
viewProperties:
|
||||
regions: null
|
||||
|
||||
initialize: (editor) ->
|
||||
@editor = editor
|
||||
@cursor = Cursor.build(editor).appendTo(this)
|
||||
@cursor = Cursor.build(this).appendTo(this)
|
||||
@regions = []
|
||||
|
||||
bufferChanged: (e) ->
|
||||
@cursor.setPosition(e.postRange.end)
|
||||
|
||||
updateScreenPosition: ->
|
||||
@cursor.updateScreenPosition()
|
||||
updateAppearance: ->
|
||||
@cursor.updateAppearance()
|
||||
@clearRegions()
|
||||
|
||||
range = @getRange()
|
||||
return if range.isEmpty()
|
||||
for row in [range.start.row..range.end.row]
|
||||
start =
|
||||
if row == range.start.row
|
||||
range.start
|
||||
else
|
||||
{ row: row, column: 0 }
|
||||
|
||||
end =
|
||||
if row == range.end.row
|
||||
range.end
|
||||
else
|
||||
null
|
||||
|
||||
@appendRegion(start, end)
|
||||
|
||||
appendRegion: (start, end) ->
|
||||
{ lineHeight, charWidth } = @editor
|
||||
top = start.row * lineHeight
|
||||
left = start.column * charWidth
|
||||
height = lineHeight
|
||||
width = if end
|
||||
end.column * charWidth - left
|
||||
else
|
||||
@editor.width() - left
|
||||
|
||||
region = $$.div(class: 'selection').css({top, left, height, width})
|
||||
@append(region)
|
||||
@regions.push(region)
|
||||
|
||||
clearRegions: ->
|
||||
region.remove() for region in @regions
|
||||
@regions = []
|
||||
|
||||
setRange: (range) ->
|
||||
@cursor.setPosition(range.start)
|
||||
@placeAnchor()
|
||||
@cursor.setPosition(range.end)
|
||||
|
||||
insertText: (text) ->
|
||||
@editor.buffer.change(@getRange(), text)
|
||||
|
||||
@@ -23,3 +23,7 @@
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.editor .selection {
|
||||
position: absolute;
|
||||
background: blue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user