Package at.bestsolution.efxclipse.styledtext.behavior

Source Code of at.bestsolution.efxclipse.styledtext.behavior.StyledTextBehavior

/*******************************************************************************
* Copyright (c) 2013 BestSolution.at and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*   Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
*******************************************************************************/
package at.bestsolution.efxclipse.styledtext.behavior;

import java.util.Set;

import javafx.event.Event;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import at.bestsolution.efxclipse.styledtext.ActionEvent;
import at.bestsolution.efxclipse.styledtext.StyledTextArea;
import at.bestsolution.efxclipse.styledtext.ActionEvent.ActionType;
import at.bestsolution.efxclipse.styledtext.VerifyEvent;
import at.bestsolution.efxclipse.styledtext.skin.StyledTextSkin.LineCell;

import com.sun.javafx.scene.control.behavior.BehaviorBase;
import com.sun.javafx.scene.text.HitInfo;

public class StyledTextBehavior extends BehaviorBase<StyledTextArea> {
  public StyledTextBehavior(StyledTextArea styledText) {
    super(styledText);
  }

  @Override
  protected void callActionForEvent(KeyEvent arg0) {
    if( arg0.getEventType() == KeyEvent.KEY_PRESSED ) {
      keyPressed(arg0, getControl().getContent().getLineAtOffset(getControl().getCaretOffset()));
    }
    super.callActionForEvent(arg0);
  }
 
  @Override
  protected void callAction(String arg0) {
    super.callAction(arg0);
  }
 
  @Override
  public void mousePressed(MouseEvent arg0) {
    super.mousePressed(arg0);
    getControl().requestFocus();
  }
 
  public boolean invokeAction(ActionType action) {
    ActionEvent evt = new ActionEvent(getControl(), getControl(), action);
    Event.fireEvent(getControl(), evt);
    return evt.isConsumed();
  }
 
  private void keyPressed(KeyEvent event, int currentRowIndex) {
    VerifyEvent evt = new VerifyEvent(getControl(), getControl(), event);
    Event.fireEvent(getControl(), evt);
   
    if( evt.isConsumed() ) {
      event.consume();
      return;
    }
   
    final int offset = getControl().getCaretOffset();
   
    switch (event.getCode()) {
    case SHIFT:
    case ALT:
    case CONTROL:
      break;
    case LEFT:
    {
      if( event.isAltDown() ) {
        invokeAction(ActionType.WORD_PREVIOUS);
      } else {
        if( offset == 0 ) {
          break;
        }
        int newOffset = offset-1;
        int currentLine = getControl().getContent().getLineAtOffset(offset);
        int newLine = getControl().getContent().getLineAtOffset(newOffset);
        getControl().setCaretOffset(newOffset);       
      }
      break;
    }
    case RIGHT:
    {
      if( event.isAltDown() ) {
        invokeAction(ActionType.WORD_NEXT);
      } else if(event.isMetaDown())  {
        int currentLine = getControl().getContent().getLineAtOffset(offset);
        int lineOffset = getControl().getContent().getOffsetAtLine(currentLine);
        String lineContent = getControl().getContent().getLine(currentLine);
       
        getControl().setCaretOffset(lineOffset + lineContent.length());
      } else {
        if( offset+1 > getControl().getContent().getCharCount() ) {
          break;
        }
        int newOffset = offset+1;
        int currentLine = getControl().getContent().getLineAtOffset(offset);
        int newLine = getControl().getContent().getLineAtOffset(newOffset);
        getControl().setCaretOffset(newOffset);       
      }
      break;
    }
    case UP:
    {
      int rowIndex = currentRowIndex;
     
      if( rowIndex == 0 ) {
        break;
      }
     
      int colIdx = offset - getControl().getContent().getOffsetAtLine(rowIndex);
      rowIndex -= 1;
     
      int lineOffset = getControl().getContent().getOffsetAtLine(rowIndex);
      int newCaretPosition = lineOffset + colIdx;
      int maxPosition      = lineOffset + getControl().getContent().getLine(rowIndex).length();
     
      getControl().setCaretOffset(Math.min(newCaretPosition, maxPosition));
      break;
    }
    case DOWN:
    {
      int rowIndex = currentRowIndex;
      if( rowIndex+1 == getControl().getContent().getLineCount() ) {
        break;
      }
     
      int colIdx = offset - getControl().getContent().getOffsetAtLine(rowIndex);
      rowIndex += 1;
     
      int lineOffset = getControl().getContent().getOffsetAtLine(rowIndex);
      int newCaretPosition = lineOffset + colIdx;
      int maxPosition      = lineOffset + getControl().getContent().getLine(rowIndex).length();
     
      getControl().setCaretOffset(Math.min(newCaretPosition, maxPosition));
      break;
    }
    case ENTER:
      int line = getControl().getContent().getLineAtOffset(getControl().getCaretOffset());
      String lineContent = getControl().getContent().getLine(line);
     
      //FIXME Temp hack
      char[] chars = lineContent.toCharArray();
      String prefix = "";
      for( int i = 0; i < chars.length; i++ ) {
        if( chars[i] == ' ' ) {
          prefix += " "
        } else {
          break;
        }
      }
     
      getControl().getContent().replaceTextRange(getControl().getCaretOffset(), 0, event.getText()+prefix);
//      listView.getSelectionModel().select(listView.getSelectionModel().getSelectedIndex()+1);
      getControl().setCaretOffset(offset+1+prefix.length());
      break;
    case DELETE:
      if( event.isMetaDown() ) {
        invokeAction(ActionType.DELETE_WORD_NEXT);
      } else {
        getControl().getContent().replaceTextRange(getControl().getCaretOffset(), 1, "");
        getControl().setCaretOffset(offset);       
      }
      break;
    case BACK_SPACE:
      if( event.isMetaDown() ) {
        invokeAction(ActionType.DELETE_WORD_PREVIOUS);
      } else {
        getControl().getContent().replaceTextRange(getControl().getCaretOffset()-1, 1, "");
        getControl().setCaretOffset(offset-1)
      }
      break;
    case TAB:
      event.consume();
      if( event.isShiftDown() ) {
        //TODO Remove first 4 white space chars???
        break;
      } else {
        //FIXME Need to should fix this but it currently completely break cursor positioning
        getControl().getContent().replaceTextRange(getControl().getCaretOffset(), 0, "    ");
        getControl().setCaretOffset(offset+4);
        break;
      }
    default:
      if( event.isMetaDown() || event.isControlDown() ) {
        // exclude meta keys
      } else {
       
        if( event.getText().length() > 0 ) {
          getControl().getContent().replaceTextRange(getControl().getCaretOffset(), 0, event.getText());
          getControl().setCaretOffset(offset+1)
        }
      }
     
      break;
    }
   
//    Event.fireEvent(getControl(), event.copyFor(getControl(), getControl()));
  }
 
  public void mousePressed(MouseEvent event, Set<LineCell> visibleCells) {
    Point2D p = new Point2D(event.getX(), event.getY());
    for( LineCell cell : visibleCells ) {
      if( cell.getBoundsInParent().contains(p) ) {
        if( cell.getDomainElement() != null ) {
          // Calculate to cell relative
          p = p.subtract(cell.getLayoutX(), cell.getLayoutY());
          Region g = (Region) cell.getGraphic();
          p = p.subtract(g.getLayoutX(), g.getLayoutY());
         
          TextFlow flow = (TextFlow) g.getChildrenUnmodifiable().get(0);
          // Calculate to text flow
          p = p.subtract(flow.getLayoutX(), flow.getLayoutY());
          for( Node n : flow.getChildren() ) {
            Text text = (Text) n;
            if( text.getBoundsInParent().contains(p) ) {
              HitInfo info = text.impl_hitTestChar(new Point2D(p.getX()-text.getLayoutX(), 0 /* See RT-28485 text.getLayoutY()*/));
              if( info.getInsertionIndex() >= 0 ) {
//                System.err.println("Text: " + text.getText());
//                System.err.println("Text-Offset: " + text.getUserData());
//                System.err.println("INSERT INDEX: " + info.getInsertionIndex());
                int offset = ((Integer)text.getUserData()).intValue()+info.getInsertionIndex();
//                System.err.println("NEW OFFSET AT: " + offset);
                getControl().setCaretOffset(offset);
                return;
              }
            }
          }
         
          int offset = cell.getDomainElement().getLineOffset() + cell.getDomainElement().getLineLength();
          getControl().setCaretOffset(offset);
        }
        break;
      }
    }
    getControl().requestFocus();
    Event.fireEvent(getControl(), event.copyFor(getControl(), getControl()));
  }
}
TOP

Related Classes of at.bestsolution.efxclipse.styledtext.behavior.StyledTextBehavior

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.