'From Squeak3.7gamma of ''17 July 2004'' [latest update: #5976] on 17 July 2004 at 11:09:12 am'! "Change Set: StringMorphEditorSelectionFix-nk Date: 12 June 2004 Author: Ned Konz Despite the warning about the selection bug, "! !CharacterBlockScanner methodsFor: 'scanning' stamp: 'nk 6/23/2003 13:31'! characterBlockAtPoint: aPoint index: index in: textLine "This method is the Morphic characterBlock finder. It combines MVC's characterBlockAtPoint:, -ForIndex:, and buildCharcterBlock:in:" | runLength lineStop done stopCondition | line _ textLine. rightMargin _ line rightMargin. lastIndex _ line first. self setStopConditions. "also sets font" characterIndex _ index. " == nil means scanning for point" characterPoint _ aPoint. (characterPoint == nil or: [characterPoint y > line bottom]) ifTrue: [characterPoint _ line bottomRight]. (text isEmpty or: [(characterPoint y < line top or: [characterPoint x < line left]) or: [characterIndex ~~ nil and: [characterIndex < line first]]]) ifTrue: [^ (CharacterBlock new stringIndex: line first text: text topLeft: line leftMargin@line top extent: 0 @ textStyle lineGrid) textLine: line]. destX _ leftMargin _ line leftMarginForAlignment: alignment. destY _ line top. runLength _ text runLengthFor: line first. characterIndex ~~ nil ifTrue: [lineStop _ characterIndex "scanning for index"] ifFalse: [lineStop _ line last "scanning for point"]. runStopIndex _ lastIndex + (runLength - 1) min: lineStop. lastCharacterExtent _ 0 @ line lineHeight. spaceCount _ 0. done _ false. [done] whileFalse: [stopCondition _ self scanCharactersFrom: lastIndex to: runStopIndex in: text string rightX: characterPoint x stopConditions: stopConditions kern: kern. "see setStopConditions for stopping conditions for character block operations." self lastCharacterExtentSetX: (specialWidth == nil ifTrue: [font widthOf: (text at: lastIndex)] ifFalse: [specialWidth]). (self perform: stopCondition) ifTrue: [characterIndex == nil ifTrue: [ "Result for characterBlockAtPoint: " (lastIndex == line last and: [ aPoint x > ((characterPoint x) + (lastCharacterExtent x / 2)) ]) ifTrue: [ "Correct for right half of last character in line" ^ (CharacterBlock new stringIndex: lastIndex + 1 text: text topLeft: characterPoint + (lastCharacterExtent x @ 0) + (font descentKern @ 0) extent: 0 @ lastCharacterExtent y) textLine: line ]. ^ (CharacterBlock new stringIndex: lastIndex text: text topLeft: characterPoint + (font descentKern @ 0) extent: lastCharacterExtent - (font baseKern @ 0)) textLine: line] ifFalse: ["Result for characterBlockForIndex: " ^ (CharacterBlock new stringIndex: characterIndex text: text topLeft: characterPoint + ((font descentKern) - kern @ 0) extent: lastCharacterExtent) textLine: line]]]! ! !StringMorphEditor methodsFor: 'event handling' stamp: 'nk 6/12/2004 22:07'! keyStroke: evt "This is hugely inefficient, but it seems to work, and it's unlikely it will ever need to be any more efficient -- it's only intended to edit single-line strings." | char priorEditor newSel | (((char _ evt keyCharacter) = Character enter) or: [(char = Character cr) or: [char = $s and: [evt commandKeyPressed]]]) ifTrue: [owner doneWithEdits; acceptContents. self flag: #arNote. "Probably unnecessary" evt hand releaseKeyboardFocus. ^ self delete]. (char = $l and: [evt commandKeyPressed]) ifTrue: "cancel" [owner cancelEdits. evt hand releaseKeyboardFocus. ^ self delete]. super keyStroke: evt. owner interimContents: self contents asString. newSel _ self editor selectionInterval. priorEditor _ self editor. "Save editor state" self releaseParagraph. "Release paragraph so it will grow with selection." self paragraph. "Re-instantiate to set new bounds" self installEditorToReplace: priorEditor. "restore editor state" self editor selectFrom: newSel first to: newSel last. ! !