SmallSenseCompletionWindow.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 30 Jan 2012 22:38:04 +0000
changeset 6 6e05842229db
parent 5 9b296f3ad0a4
child 18 cebd9550b288
permissions -rw-r--r--
Compilation fix

"{ Package: 'stx:libtool/smallsense' }"

SimpleDialog subclass:#SmallSenseCompletionWindow
	instanceVariableNames:'codeView result position textHolder selectionHolder
		selectionUnambigous listHolder'
	classVariableNames:''
	poolDictionaries:''
	category:'SmallSense-Interface'
!


!SmallSenseCompletionWindow class methodsFor:'interface opening'!

openForView: codeView class: class

    ^self new  
        initializeForView: codeView class: class;
        completeOrOpen.

    "Created: / 04-04-2011 / 11:54:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 26-11-2011 / 19:07:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseCompletionWindow class methodsFor:'interface specs'!

windowSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:SmallSenseCompletionWindow andSelector:#windowSpec
     SmallSenseCompletionWindow new openInterface:#windowSpec
     SmallSenseCompletionWindow open
    "

    <resource: #canvas>

    ^ 
     #(FullSpec
        name: windowSpec
        window: 
       (WindowSpec
          label: 'SmallSenseMenu'
          name: 'SmallSenseMenu'
          min: (Point 10 10)
          bounds: (Rectangle 0 0 400 250)
          returnIsOKInDialog: false
        )
        component: 
       (SpecCollection
          collection: (
           (SelectionInListModelViewSpec
              name: 'Completions'
              layout: (LayoutFrame 0 0 0 0 0 1 0 1)
              model: selectionHolder
              hasHorizontalScrollBar: true
              hasVerticalScrollBar: true
              miniScrollerHorizontal: true
              backgroundColor: (Color 100.0 100.0 100.0)
              listModel: listHolder
              useIndex: false
              highlightMode: line
              postBuildCallback: postBuildList:
            )
           )
         
        )
      )
! !

!SmallSenseCompletionWindow methodsFor:'aspects'!

listHolder

    
    listHolder isNil 
        ifTrue:
            [ listHolder := ValueHolder new].
    ^ listHolder.

    "Modified: / 04-04-2011 / 21:26:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

selectionHolder
    <resource: #uiAspect>

    "automatically generated by UIPainter ..."

    "*** the code below creates a default model when invoked."
    "*** (which may not be the one you wanted)"
    "*** Please change as required and accept it in the browser."
    "*** (and replace this comment by something more useful ;-)"

    selectionHolder isNil ifTrue:[
        selectionHolder := ValueHolder new.
"/ if your app needs to be notified of changes, uncomment one of the lines below:
"/       selectionHolder addDependent:self.
"/       selectionHolder onChangeSend:#selectionHolderChanged to:self.
    ].
    ^ selectionHolder.
!

textHolder
    "return/create the 'textHolder' value holder (automatically generated)"

    textHolder isNil ifTrue:[
        textHolder := ValueHolder with:''.
        textHolder onChangeSend:#updateList to: self.
    ].
    ^ textHolder

    "Modified: / 26-11-2011 / 17:25:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseCompletionWindow methodsFor:'change & update'!

updateList

    "Experiments with new UI"

    | t |
    result items size == 0 ifTrue:[^self].

    t := self textHolder value.
    self listHolder value isNil ifTrue:
        [self listHolder value:result items].
    [ t size > 0 ] whileTrue:[
        result items withIndexDo: [:e :i| 
            (e startsWith: t) ifTrue: [
                self selectionHolder value: e.
                ^self
            ]
        ].
        t := t allButLast.
    ]

    "
    | t list |
    t := self textHolder value.
    list := (result objectCollection select:[:e|e stringToComplete startsWith: t]).
    self listHolder value: list.
    list size = 1 ifTrue:[self selectionHolder value: list anyOne].
    "

    "Created: / 04-04-2011 / 15:43:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 26-11-2011 / 19:25:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseCompletionWindow methodsFor:'events'!

complete
    | selection text lineNo line |

    selection := self selectionHolder value stringToComplete.
    text := self textHolder value.
    lineNo := codeView cursorLine.
    line := codeView list at: (lineNo min: codeView list size).
    line := ((line size < (codeView cursorCol - text size - 1)) 
                ifTrue: [line , (String new: (codeView cursorCol - text size - 1 - line size))]
                ifFalse:[line copyTo: codeView cursorCol - text size - 1])
                , selection 
                    , (line copyFrom: codeView cursorCol + 1).
    codeView list at: lineNo put: line.
    codeView cursorCol: codeView cursorCol - text size + self selectionHolder value cursorColumnAfterComplete.
    codeView redrawLine:lineNo.

    "Created: / 26-11-2011 / 19:10:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

handlesKeyPress:key inView:aView

    "/Transcript showCR: 'SmallSenseCompletionWindow handlesKeyPress: ' , key.
    key isCharacter ifTrue:[^true].
    ^#(BackSpace Return) includes: key

    "Created: / 04-04-2011 / 15:52:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 05-04-2011 / 00:03:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

keyPress:key x:x y:y view:aView

    "/Transcript showCR: 'SmallSenseCompletionWindow keyPress: ' , key.

    key isCharacter ifTrue:[self keyPressCharacter: key x:x y:y. ^self].
    key == #BackSpace ifTrue:[self keyPressBackSpaceX:x y:y.^self].
    key == #Return ifTrue:[self keyPressReturnX:x y:y.^self]

    "Created: / 04-04-2011 / 15:51:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 05-04-2011 / 00:03:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

keyPressBackSpaceX:x y:y

    | text |
    codeView textView keyPress:#BackSpace x:x y:y.
    text := self textHolder value.
    text size == 0 ifTrue:[self close. ^self].
    self textHolder value: (text copyTo: text size - 1).

    "Created: / 04-04-2011 / 16:56:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 08-04-2011 / 22:49:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

keyPressCharacter: char x:x y:y

    | text |
    text := self textHolder value.
    self textHolder value: (text , char).
    codeView textView keyPress:char x:x y:y.

    "Created: / 04-04-2011 / 16:56:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

keyPressReturnX:x y:y

    self selectionHolder value isNil ifTrue:[self close.^self].
    self complete.
    self close.

    "Created: / 04-04-2011 / 16:57:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified (format): / 26-11-2011 / 19:11:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseCompletionWindow methodsFor:'hooks'!

postBuildList: listView

    listView scrolledView
        background: codeView background;
        font: codeView font;
        delegate: self.

    "Created: / 03-04-2011 / 10:39:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 04-04-2011 / 15:50:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

postBuildWith: builder

    builder window 
        windowGroup: codeView windowGroup;
        bePopUpView; 
        beSlave.
    builder window sensor setCtrlDown: false.

    "Created: / 03-04-2011 / 10:45:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 02-06-2011 / 21:36:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseCompletionWindow methodsFor:'initialization'!

initializeForView: view class: class

    | p node |
    
    codeView := view.
    p := codeView characterPositionOfCursor.
    result := SmallSenseRecognizer
                            resultSetFor: codeView mode
                            source: codeView contents
                            class: class
                            line: codeView cursorLine
                            column: codeView cursorCol.

    result isEmpty ifFalse:[
        (p := result position) notNil ifTrue:[
            node := p node.                    
            node notNil ifTrue:[
                (node isVariable and:[p inNode]) ifTrue:[
                    self textHolder value: node name
                ] ifFalse:[node isMessage ifTrue:[
                    self textHolder value: node selector
                ]].
            ].            
        ].
        self updateList
    ].

    "Created: / 04-04-2011 / 11:56:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 06-04-2011 / 17:37:25 / Jakub <zelenja7@fel.cvut.cz>"
    "Modified: / 27-11-2011 / 10:06:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseCompletionWindow methodsFor:'interface opening'!

completeOrOpen

    | text matching v|

    result isEmpty ifTrue:[^self].

    (text := textHolder value) notEmptyOrNil ifTrue:[
        matching := result items select:[:item|item startsWith: text].
        matching size == 1 ifTrue:[
            v := matching anElement.
            (v := selectionHolder value) notNil ifTrue:[
                (v isSmallSenseVariable or:[v isSmallSenseClass]) ifTrue:[
                    self complete.
                    ^self.
                ]
            ].        
       ].
    ].

    self openModal.

    "Created: / 26-11-2011 / 19:08:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

openModal

    | p textView x y |

    textView := codeView textView.
    x := (textView xOfCol:textView cursorCol  inVisibleLine:textView cursorLine)
            - 16"icon" - (textView widthOfString: self textHolder value) - 5"magic constant".
    y := textView yOfCursor + textView font maxHeight + 3.
    p := (textView originRelativeTo: nil) + (x @ y).

    self openInterfaceModal:#windowSpec at:p

    "Created: / 04-04-2011 / 21:12:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!SmallSenseCompletionWindow class methodsFor:'documentation'!

version_SVN
    ^ '$Id: SmallSenseCompletionWindow.st 7858 2012-01-30 22:38:04Z vranyj1 $'
! !