    001package org.vishia.gral.base;
    002
    003import org.vishia.gral.ifc.GralUserAction;
    004import org.vishia.gral.ifc.GralWidget_ifc;
    005import org.vishia.util.KeyCode;
    006
    007/**The main key listener.
    008 * <b>Processing of keys</b>: (2012-06-17)<br>
    009 * Key events are produced by the underlying graphic operation system. Usual they are applied to the widgets of the
    010 * operation system graphic. For example, key left and right are used to navigate in a text field.
    011 * <br><br>
    012 * On system graphic level any widget can have its key listener. Then the keys are applied to it, the listener determines
    013 * what to do with keys. Usual the key is applied to the standard behavior of the widget after them.
    014 * But the key event may be set to 'do not do it' in the key listener. Then the standard behavior of the key in that widget is prevent.
    015 * <br><br>
    016 * The action for some keys may be determined for a special widget or widget type in an graphic system independent way.
    017 * The {@link GralWidget#setActionChange(org.vishia.gral.ifc.GralUserAction)} method can be given for any widget.
    018 * The {@link GralUserAction#userActionGui(int, GralWidget, Object...)} will be invoked with the {@link KeyCode}
    019 * and the widget reference. But firstly the {@link #specialKeysOfWidgetType(int, GralWidget)} is called.
    020 * This method may be overridden for the widget type. If it returns true, the key code is not applied to any user action,
    021 * it is a widget-special key.
    022 * <br><br>
    023 * If that method returns false or a {@link GralWidget#getActionChange()} action is not given for this widget,
    024 * the key will be applied to the {@link GralMng#setMainKeyAction(org.vishia.gral.ifc.GralUserAction)}.
    025 * In that way a application-global usage of some keys is organized.
    026 * <br><br>
    027 * If any of the both widget specific or global {@link GralUserAction#userActionGui(int, GralWidget, Object...)} method
    028 * returns true, the key is not used for the widget in the graphic system. In that kind some keys can be blocked
    029 * for standard behavior.
    030 * <br><br>
    031 * <b>class diagramm of usage for example in SWT: </b>
    032 * <pre>
    033 *                                                                 GralWidget <------------|
    034 *                                                                                         |
    035 *    SwtSpecialWidgetKeyListener ----|> SwtKeyListner ----|> swt.KeyListener <------- SwtWidget
    036 *    + specialKeysOfWidgetType()                  |
    037 *                                           |<----|
    038 *                                           |
    039 *    GralSpecialWidgetKeyListener ---|> GralKeyListener
    040 *    +specialKeysOfWidgetType()             * keyPressed(key, gralWidg)
    041 *                                                * gralWidg.getActionChange().userActionGui(...)
    042 *                                                * mng.userMainKeyAction().userActionGui(...)
    043 *
    044 *  </pre>
    045 *  (See {@link org.vishia.util.Docu_UML_simpleNotation})
    046 *  <br><br>
    047 *  The implementing graphic system aggregates an instance of this class.
    048 *  An underived instance is created in the {@link GralMng.InternalPublic#gralKeyListener}.
    049 *  This instance can be used as aggregation in all implementing system listeners, if the
    050 *  {@link #specialKeysOfWidgetType(int, GralWidget)} should not overridden.
    051 *
    052 * @author Hartmut Schorrig
    053 *
    054 */
    055public class GralKeyListener implements GralKeySpecial_ifc
    056{
    057  /**Version, history and license
    058   * <ul>
    059   * <li>2011-12-03 Hartmut created. Any widget may have the same key listener. It is the baseclass of it
    060   *   and empty yet.
    061   * </ul>
    062   *
    063   * <b>Copyright/Copyleft</b>:
    064   * For this source the LGPL Lesser General Public License,
    065   * published by the Free Software Foundation is valid.
    066   * It means:
    067   * <ol>
    068   * <li> You can use this source without any restriction for any desired purpose.
    069   * <li> You can redistribute copies of this source to everybody.
    070   * <li> Every user of this source, also the user of redistribute copies
    071   *    with or without payment, must accept this license for further using.
    072   * <li> But the LPGL ist not appropriate for a whole software product,
    073   *    if this source is only a part of them. It means, the user
    074   *    must publish this part of source,
    075   *    but don't need to publish the whole source of the own product.
    076   * <li> You can study and modify (improve) this source
    077   *    for own using or for redistribution, but you have to license the
    078   *    modified sources likewise under this LGPL Lesser General Public License.
    079   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
    080   * </ol>
    081   * If you are intent to use this sources without publishing its usage, you can get
    082   * a second license subscribing a special contract with the author.
    083   *
    084   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
    085   *
    086   *
    087   */
    088  public final static int version = 20120609;
    089
    090
    091  protected final GralMng mng;
    092
    093
    094  public GralKeyListener(GralMng mng){
    095    this.mng = mng;
    096  }
    097
    098
    099
    100  public boolean keyPressed(int keyCode, GralWidget_ifc widgi, Object widgImpl){
    101    boolean actionDone;
    102    GralWidget_ifc.ActionChange action = widgi.getActionChange(GralWidget_ifc.ActionChangeWhen.onAnyChgContent);
    103    if(action !=null){
    104      Object[] args = action.args();
    105    }
    106    final GralMng mng = widgi.gralMng();
    107    try{
    108      actionDone = specialKeysOfWidgetType(keyCode, widgi, widgImpl);
    109      if(!actionDone && action !=null){
    110        Object[] args = action.args();
    111        if(args == null){ actionDone = action.action().exec(keyCode, widgi); }
    112        else { actionDone = action.action().exec(keyCode, widgi, args); }
    113      } //if(table.)
    114      if(!actionDone && mng.userMainKeyAction() !=null){
    115        actionDone = mng.userMainKeyAction().exec(keyCode, widgi);
    116      }
    117      if(!actionDone){
    118        GralUserAction mainKeyAction = mng.getRegisteredUserAction("KeyAction");
    119        if(mainKeyAction !=null){
    120          //old form called because compatibility, if new for with int-parameter returns false.
    121          if(!mainKeyAction.exec(keyCode, widgi)){
    122            mainKeyAction.exec(keyCode, widgi, new Integer(keyCode));
    123          }
    124        }
    125      }
    126    } catch(Exception exc){
    127      mng.log.sendMsg(0, "KeyListener - UsercallException; key=%8x; %s;", keyCode, exc.getLocalizedMessage());
    128    }
    129
    130    return true;
    131  }
    132
    133
    134  @Override public boolean specialKeysOfWidgetType(int key, GralWidget_ifc widgg, Object widgImpl){ return false; }
    135
    136
    137}