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}