Package com.vk.gwt.designer.client.designer

Source Code of com.vk.gwt.designer.client.designer.VkEventTextArea

/*
* Copyright 2011 Gaurav Saxena < gsaxena81 AT gmail.com >
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vk.gwt.designer.client.designer;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;

public class VkEventTextArea extends Composite {
  private FocusPanel fp = new FocusPanel();
  private TextArea ta = new TextArea();
  private JavaScriptObject editor;
  private PopupPanel autoCompletePanel = new PopupPanel();
  public VkEventTextArea() {
    initWidget(fp);
    fp.setSize("100%", "100%");
    DOM.setStyleAttribute(fp.getElement(), "border", "solid 1px gray");
    ScrollPanel scrollPanel = new ScrollPanel();
    autoCompletePanel.add(scrollPanel);
    VerticalPanel optionsHolderPanel = new VerticalPanel();
    scrollPanel.add(optionsHolderPanel);
    DOM.setStyleAttribute(autoCompletePanel.getElement(), "zIndex", Integer.MAX_VALUE + "");
    fp.add(ta);
    fp.addMouseDownHandler(new MouseDownHandler() {
      @Override
      public void onMouseDown(MouseDownEvent event) {
        String id = getRealElementId(Element.as(event.getNativeEvent().getEventTarget()));
        if(!id.isEmpty()) {
          addElementId(id);
          DOM.setCapture(VkEventTextArea.this.getElement());//Using VkDesignerUtil.setCapture / releaseCapture causes IE 9  to have 2 captures and pop up doesn't move
        } else
          DOM.releaseCapture(VkEventTextArea.this.getElement());
        new Timer(){
          @Override
          public void run() {
            focus();
          }}.schedule(1);
      }
    });
    fp.addMouseOutHandler(new MouseOutHandler() {
      @Override
      public void onMouseOut(MouseOutEvent event) {
        if(DOM.getCaptureElement() == null)
          DOM.setCapture(VkEventTextArea.this.getElement());
      }
    });
    fp.addBlurHandler(new BlurHandler() {
      @Override
      public void onBlur(BlurEvent event) {
        DOM.releaseCapture(getElement());
      }
    });
    fp.addKeyDownHandler(new KeyDownHandler(){
      @Override
      public void onKeyDown(KeyDownEvent event) {
        event.stopPropagation();
      }});
  }
  private void showSuggestions(int keyCode) {
    String sentence = getText();
    int startIndex = sentence.length() - 1;
    String elementId = "";
    while(startIndex >= 0 && sentence.charAt(startIndex--) != '.');
    if(startIndex != 0 && startIndex < sentence.length() - 2) {
      String phrase = startIndex == sentence.length() - 1 ? "" : sentence.substring(startIndex + 2);//after the dot is found
      startIndex++;//startIndex points at dot now
      if(startIndex > 0 && sentence.charAt(--startIndex) == ')') {
        char nextChar;
        while(startIndex > 0 && Character.isDigit(nextChar = sentence.charAt(--startIndex)))
          elementId += nextChar;
        if(startIndex > 0 && sentence.charAt(startIndex) == '(')
        {
          if(startIndex > 0 && sentence.charAt(--startIndex) == '&')
            showFunctions(elementId, phrase);
        }
      }
    }
  }
  private native void showFunctions(String elementId, String phrase) /*-{
    var elem = $doc.getElementById(elementId);
    var functions = '';
    var j = 0;
    for(i in elem)
      if(i.toLowerCase().indexOf(phrase.toLowerCase()) == 0 && i.indexOf('_') != 0)
        functions += i + ',';
    var coords = this.@com.vk.gwt.designer.client.designer.VkEventTextArea::editor.cursorCoords(true);
    this.@com.vk.gwt.designer.client.designer.VkEventTextArea::showAutoComplete(Ljava/lang/String;Lcom/google/gwt/dom/client/Element;III)(functions, elem, phrase.length, coords.x, coords.y);
  }-*/;
  private void showAutoComplete(String optionString, final com.google.gwt.dom.client.Element element, final int phraseLength, int x, int y) {
    final String[] options = optionString.split(",");
    ScrollPanel scrollPanel = (ScrollPanel)autoCompletePanel.getWidget();
    VerticalPanel optionHolderPanel = (VerticalPanel)scrollPanel.getWidget();
    optionHolderPanel.clear();
    for (int i = 0, len = options.length; i < len; i++)  {
      final Anchor option = getOption(options[i]);
      final int optionsNum = i;
      optionHolderPanel.add(option);
      option.addClickHandler(new ClickHandler(){
        @Override
        public void onClick(ClickEvent event) {
          setAutoCompleteOption(options[optionsNum], phraseLength, element);
          autoCompletePanel.hide();
        }});
    }
    autoCompletePanel.setAutoHideEnabled(true);
    autoCompletePanel.setPopupPosition(x, y + 10);
    autoCompletePanel.show();
    scrollPanel.setSize("200px",Math.min(optionHolderPanel.getOffsetHeight(), 300) + "px");
  }
  private native void setAutoCompleteOption(String autoCompleteText, int phraseLength, com.google.gwt.dom.client.Element element) /*-{
    var editor = this.@com.vk.gwt.designer.client.designer.VkEventTextArea::editor;
    var cursorPos = editor.getCursor(true);
    var value = element[autoCompleteText];
    if(typeof value == 'function')
      autoCompleteText += '()';
    editor.replaceRange(autoCompleteText, {line: cursorPos.line, ch: cursorPos.ch - phraseLength},
    {line: cursorPos.line, ch: cursorPos.ch});
    editor.focus();
  }-*/;
  private Anchor getOption(String option) {
    final Anchor optionLabel = new Anchor(option);
    optionLabel.setStyleName("eventcode-autocomplete");
    return optionLabel;
  }
  @Override
  public void onLoad() {
    editor = initCodeMirror(ta.getElement());
    DOM.setCapture(getElement());
    new Timer(){
      @Override
      public void run() {
        try{
          focus();
        }catch(Exception e)  {
          schedule(200);
        }
      }
    }.schedule(200);
  }
  private native void addElementId(String id)/*-{
    var editor = this.@com.vk.gwt.designer.client.designer.VkEventTextArea::editor;
    var cursorPos = editor.getCursor(true);
    var stringId = "&(" +  id + ")";
    editor.replaceRange(stringId, {line: cursorPos.line, ch: cursorPos.ch});
    editor.focus();
  }-*/;
  private native JavaScriptObject initCodeMirror(Element textarea)/*-{
    var vkEventTextArea = this;
    return $wnd.CodeMirror.fromTextArea(textarea, {    
       matchBrackets: true,
       mode:  "javascript",
       onKeyEvent: function(editor, keyEvent){
        var keyCode = keyEvent.keyCode;
        if((keyEvent.ctrlKey && keyCode == 32)) {
          vkEventTextArea.@com.vk.gwt.designer.client.designer.VkEventTextArea::showSuggestions(I)(keyCode);
          if(keyEvent.preventDefault)
            keyEvent.preventDefault();
          else
            keyEvent.returnValue = false;
        }
      }
     });
  }-*/;
  public native String getText()/*-{
    return this.@com.vk.gwt.designer.client.designer.VkEventTextArea::editor.getValue().replace(/\s+/g,' ');
  }-*/;
  public void setText(final String text){
    new Timer(){
      @Override
      public void run() {
        try{
          if(editor != null)
            populateJs(editor, text.replaceAll(";", ";\n").replaceAll("\\{","{\n").replaceAll("\\}","}\n").trim());
          else
            schedule(200);
        } catch(Exception e) {
          schedule(200);//editor is not initialized properly
        }
      }
      private native void populateJs(JavaScriptObject editor, String text) /*-{
        editor.replaceRange(text, {line: 0, ch: 0});
        editor.refresh();
      }-*/;
    }.schedule(200);
  }
  private native void setText(JavaScriptObject editor, String text, int lineNum, int charNum) /*-{
    editor.replaceRange(text, {line: lineNum, ch: charNum});
  }-*/;
  private String getRealElementId(com.google.gwt.dom.client.Element element) {
    com.google.gwt.dom.client.Element currentElement = element;
    while(currentElement != null && currentElement.getId().isEmpty())
      currentElement = currentElement.getParentElement();
    if(currentElement != null && currentElement != VkMainDrawingPanel.getInstance().getElement())
      return currentElement.getId();
    else
      return "";
  }
  public void addMouseDownHandler(MouseDownHandler mouseDownHandler) {
    ta.addMouseDownHandler(mouseDownHandler);
  }
  public void setFocus(boolean b) {
    focus();
  }
  private native void focus() /*-{
    this.@com.vk.gwt.designer.client.designer.VkEventTextArea::editor.focus();
  }-*/;
}
TOP

Related Classes of com.vk.gwt.designer.client.designer.VkEventTextArea

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.