javauis/lcdui_qt/src/javax/microedition/lcdui/Canvas.java
changeset 79 2f468c1958d0
parent 61 bf7ee68962da
equal deleted inserted replaced
76:4ad59aaee882 79:2f468c1958d0
   157     private static final int FULLSCREEN_MODE = 1 << 2;
   157     private static final int FULLSCREEN_MODE = 1 << 2;
   158 
   158 
   159     private static final int DISABLE_TAPDETECTION = 1 << 3;
   159     private static final int DISABLE_TAPDETECTION = 1 << 3;
   160     private static final int SUPPRESS_GAMEKEYS = 1 << 4;
   160     private static final int SUPPRESS_GAMEKEYS = 1 << 4;
   161     private static final int SUPPRESS_DRAGEVENT = 1 << 5;
   161     private static final int SUPPRESS_DRAGEVENT = 1 << 5;
   162     private static final int CLEANUP_NEEDED = 1 << 6;
       
   163     private static final int REPAINT_PENDING = 1 << 7;
   162     private static final int REPAINT_PENDING = 1 << 7;
   164     private static final int SELECTIONKEY_COMPATIBILITY = 1 << 8;
   163     private static final int SELECTIONKEY_COMPATIBILITY = 1 << 8;
   165 
   164 
   166     private static final int CURRENTLY_VISIBLE = 1 << 9;
   165     private static final int CURRENTLY_VISIBLE = 1 << 9;
   167 
   166 
   203     private Composite canvasComp;
   202     private Composite canvasComp;
   204     private Label tickerLabel;
   203     private Label tickerLabel;
   205 
   204 
   206     private int mode;
   205     private int mode;
   207     private Object modeLock;
   206     private Object modeLock;
   208     private Object cleanupLock;
       
   209     private Object repaintLock;
   207     private Object repaintLock;
   210     private Object flushLock;
   208     private Object flushLock;
   211 
   209 
   212     private Timer timer = new Timer();
   210     private Timer timer = new Timer();
   213     private CanvasTimerTask timerTask;
   211     private CanvasTimerTask timerTask;
   237             objectCount++;
   235             objectCount++;
   238         }
   236         }
   239 
   237 
   240         modeLock = new Object();
   238         modeLock = new Object();
   241         repaintLock = new Object();
   239         repaintLock = new Object();
   242         cleanupLock = new Object();
       
   243         flushLock = new Object();
   240         flushLock = new Object();
   244         setMode(GAME_CANVAS, this instanceof GameCanvas);
   241         setMode(GAME_CANVAS, this instanceof GameCanvas);
   245         construct();
   242         construct();
   246         keysPressed = new Vector();
   243         keysPressed = new Vector();
   247     }
   244     }
   297      */
   294      */
   298     Shell eswtConstructShell(int style)
   295     Shell eswtConstructShell(int style)
   299     {
   296     {
   300         if(isMode(GAME_CANVAS))
   297         if(isMode(GAME_CANVAS))
   301         {
   298         {
   302             mShell = super.eswtConstructShell(style);
   299             mShell = super.eswtConstructShell(style|SWT.NO_BACKGROUND);
   303         }
   300         }
   304         else
   301         else
   305         {
   302         {
   306             if(sharedShell == null)
   303             if(sharedShell == null)
   307             {
   304             {
   308                 sharedShell = super.eswtConstructShell(style);
   305                 sharedShell = super.eswtConstructShell(style|SWT.NO_BACKGROUND);
   309             }
   306             }
   310             mShell = sharedShell;
   307             mShell = sharedShell;
   311         }
   308         }
   312 
   309 
   313         // Give the Shell the maximized size already before it becomes visible
   310         // Give the Shell the maximized size already before it becomes visible
   579     }
   576     }
   580 
   577 
   581     /**
   578     /**
   582      * Issues the request to repaint the whole Canvas.
   579      * Issues the request to repaint the whole Canvas.
   583      */
   580      */
   584     public void repaint()
   581      public final void repaint()
   585     {
   582     {
   586         repaint(0, 0, getWidth(), getHeight());
   583         repaint(0, 0, getWidth(), getHeight());
   587     }
   584     }
   588 
   585 
   589     /**
   586     /**
   593      * @param x - left bound of the rectangle to redraw.
   590      * @param x - left bound of the rectangle to redraw.
   594      * @param y - top bound of the rectangle to redraw.
   591      * @param y - top bound of the rectangle to redraw.
   595      * @param width - width of the rectangle to redraw.
   592      * @param width - width of the rectangle to redraw.
   596      * @param height - height of the rectangle to redraw.
   593      * @param height - height of the rectangle to redraw.
   597      */
   594      */
   598     public void repaint(int x, int y, int width, int height)
   595     public final void repaint(int x, int y, int width, int height)
   599     {
   596     {
   600         // Paint callback event is posted without any invalid area info.
   597         // Paint callback event is posted without any invalid area info.
   601         // Invalid area info is kept in the member variables. Only one event
   598         // Invalid area info is kept in the member variables. Only one event
   602         // per Canvas is added to the queue. If there are more repaint() calls
   599         // per Canvas is added to the queue. If there are more repaint() calls
   603         // before the already posted event has been served those are merged
   600         // before the already posted event has been served those are merged
   717     {
   714     {
   718         return true;
   715         return true;
   719     }
   716     }
   720 
   717 
   721     /**
   718     /**
   722      * Returns game action for a specified key code.
   719      * Returns game action associated with key code.
   723      *
   720      *
   724      * @param keyCode Key code to map to game action.
   721      * @param keyCode Key code to map to game action.
   725      * @return Game action for a a specified key code or
   722      * @return game action corresponding to key, or 0 if none
   726      *         IllegalArgumentException.
   723      * @throws IllegalArgumentException if keyCode is not a valid
   727      */
   724      */
   728     public int getGameAction(int keyCode)
   725     public int getGameAction(int aKeyCode)
   729     {
   726     {
   730         return KeyTable.getGameAction(keyCode);
   727         if (aKeyCode == 0)
       
   728         {
       
   729             throw new IllegalArgumentException(
       
   730                 MsgRepository.CANVAS_EXCEPTION_INVALID_KEY_CODE);
       
   731         }
       
   732         return KeyTable.getGameAction(aKeyCode);
   731     }
   733     }
   732 
   734 
   733     /**
   735     /**
   734      * Returns the key code specific for a certain game action.
   736      * Returns the key code specific for a certain game action.
   735      *
   737      *
   736      * @param gameAction - game action to be mapped to the key code.
   738      * @param gameAction - game action to be mapped to the key code.
   737      * @return Key code that is mapped to the specified game action.
   739      * @return Key code that is mapped to the specified game action.
   738      */
   740      * @throws IllegalArgumentException for not valid gameAction
   739     public int getKeyCode(int gameAction)
   741      */
   740     {
   742     public int getKeyCode(int aGameAction)
   741         return KeyTable.getKeyCode(gameAction);
   743     {
       
   744         int keyCode = KeyTable.getKeyCode(aGameAction);
       
   745 
       
   746         if (keyCode == 0)
       
   747         {
       
   748             throw new IllegalArgumentException(
       
   749                 MsgRepository.CANVAS_EXCEPTION_INVALID_GAME_ACTION);
       
   750         }
       
   751         return keyCode;
   742     }
   752     }
   743 
   753 
   744     /**
   754     /**
   745      * Returns the key name specific for a certain key code.
   755      * Returns the key name specific for a certain key code.
   746      *
   756      *
   747      * @param keyCode - key name to get the name of.
   757      * @param keyCode - key name to get the name of.
   748      * @return String that contains textual name of the key specified by the key
   758      * @return String that contains textual name of the key specified by the key
   749      *         code.
   759      *         code.
   750      */
   760      */
   751     public String getKeyName(int keyCode)
   761     public String getKeyName(int aKeyCode)
   752     {
   762     {
   753         return KeyTable.getKeyName(keyCode);
   763         return KeyTable.getKeyName(aKeyCode);
   754     }
   764     }
   755 
   765 
   756     /**
   766     /**
   757      * Callback to be implemented by the application to render the
   767      * Callback to be implemented by the application to render the
   758      * <code>Canvas</code>. The clip region of <code>Graphics</code> object
   768      * <code>Canvas</code>. The clip region of <code>Graphics</code> object
   961         super.handleShellActivatedEvent();
   971         super.handleShellActivatedEvent();
   962 
   972 
   963         // reset the game key state
   973         // reset the game key state
   964         gameKeyState = 0;
   974         gameKeyState = 0;
   965 
   975 
   966         synchronized(cleanupLock)
       
   967         {
       
   968             setMode(CLEANUP_NEEDED, true);
       
   969         }
       
   970 
       
   971         LCDUIEvent event = EventDispatcher.instance().newEvent(LCDUIEvent.CANVAS_SHOWNOTIFY, this);
   976         LCDUIEvent event = EventDispatcher.instance().newEvent(LCDUIEvent.CANVAS_SHOWNOTIFY, this);
   972         EventDispatcher.instance().postEvent(event);
   977         EventDispatcher.instance().postEvent(event);
   973     }
   978     }
   974 
   979 
   975     /**
   980     /**
   990         super.eswtHandleResizeEvent(width, height);
   995         super.eswtHandleResizeEvent(width, height);
   991         // update new bounds to graphicsBuffer
   996         // update new bounds to graphicsBuffer
   992         // this call must not be synchronized as we
   997         // this call must not be synchronized as we
   993         // cannot use locking in UI thread
   998         // cannot use locking in UI thread
   994         graphicsBuffer.setControlBounds(getContentComp());
   999         graphicsBuffer.setControlBounds(getContentComp());
   995         synchronized(cleanupLock)
       
   996         {
       
   997             setMode(CLEANUP_NEEDED, true);
       
   998         }
       
   999     }
  1000     }
  1000 
  1001 
  1001     /*
  1002     /*
  1002      * UI thread calls
  1003      * UI thread calls
  1003      */
  1004      */
  1172                 canvasGraphics = graphicsBuffer.getGraphics();
  1173                 canvasGraphics = graphicsBuffer.getGraphics();
  1173                 canvasGraphics.setSyncStrategy(Graphics.SYNC_LEAVE_SURFACE_SESSION_OPEN);
  1174                 canvasGraphics.setSyncStrategy(Graphics.SYNC_LEAVE_SURFACE_SESSION_OPEN);
  1174             }
  1175             }
  1175 
  1176 
  1176             // Clean the background if dirty, buffer the operations.
  1177             // Clean the background if dirty, buffer the operations.
  1177             synchronized(cleanupLock)
  1178             if(isMode(NO_BACKGROUND) && event.type == LCDUIEvent.CANVAS_PAINT_NATIVE_REQUEST)
  1178             {
  1179             {
  1179                 if(isMode(CLEANUP_NEEDED) && isMode(NO_BACKGROUND))
  1180                 canvasGraphics.setClip(event.x, event.y, event.width, event.height);
  1180                 {
  1181                 canvasGraphics.cleanBackground(new Rectangle(event.x, event.y, event.width, event.height));
  1181                     // UI thread can change the contentArea object reference at
       
  1182                     // any time. Store the object reference locally to ensure it
       
  1183                     // points to the same rectangle all the time.
       
  1184                     Rectangle contentArea = getContentArea();
       
  1185 
       
  1186                     canvasGraphics.setClip(contentArea.x, contentArea.y,
       
  1187                                            contentArea.width, contentArea.height);
       
  1188                     canvasGraphics.cleanBackground(contentArea);
       
  1189                     setMode(CLEANUP_NEEDED, false);
       
  1190                 }
       
  1191             }
  1182             }
  1192 
  1183 
  1193             // Clip must define the invalid area
  1184             // Clip must define the invalid area
  1194             canvasGraphics.reset();
  1185             canvasGraphics.reset();
  1195             canvasGraphics.setClip(redrawNowX, redrawNowY, redrawNowW, redrawNowH);
  1186             canvasGraphics.setClip(redrawNowX, redrawNowY, redrawNowW, redrawNowH);
  1336     }
  1327     }
  1337 
  1328 
  1338     /**
  1329     /**
  1339      * Updates game key states and returns if the key was a game key.
  1330      * Updates game key states and returns if the key was a game key.
  1340      */
  1331      */
  1341     private boolean updateGameKeyState(int keyCode, boolean addKeyState)
  1332     private boolean updateGameKeyState(int aKeyCode, boolean aAddKeyState)
  1342     {
  1333     {
  1343         // Ignore key repeat events
  1334         // Ignore key repeat events
  1344         if(ESWTUIThreadRunner.getKeyRepeatCount() > 1)
  1335         if(ESWTUIThreadRunner.getKeyRepeatCount() > 1)
  1345         {
  1336         {
  1346             return true;
  1337             return true;
  1347         }
  1338         }
  1348         try
  1339         try
  1349         {
  1340         {
  1350             int gameAction = KeyTable.getGameAction(keyCode);
  1341             int gameAction = getGameAction(aKeyCode);
  1351             if(addKeyState)
  1342             boolean result = false;
  1352             {
  1343 
  1353                 // set bitfield
  1344             // Key state should be updated only if game action 
  1354                 gameKeyState |= (1 << gameAction);
  1345             // is associated with keyCode
  1355             }
  1346             if(gameAction != 0)
  1356             return true;
  1347             {
       
  1348                 if(aAddKeyState)
       
  1349                 {
       
  1350                     // set bitfield
       
  1351                     gameKeyState |= (1 << gameAction);
       
  1352                 }
       
  1353                 result = true;
       
  1354             }
       
  1355             return result;
  1357         }
  1356         }
  1358         catch(IllegalArgumentException iae)
  1357         catch(IllegalArgumentException iae)
  1359         {
  1358         {
  1360             return false;
  1359             return false;
  1361         }
  1360         }