title: Blackberry custom OVERLAY horizontal menu
body: <p>Thanks to Max in <a href="https://stackoverflow.com/questions/2656169/blackberry-custom-menu-toolbar">this post</a>, I made an horizontal menu. But now I'm trying to make an overlay menu, i I don't find how to do that... Let's see what i got first.</p>
  
  <p>So, I have a class MapScreen which display my map:</p>
  
  <pre><code>public class MapScreen extends MenuScreen
  </code></pre>
  
  <p>Then, I have in the same file the MenuScreen class like this that allows to display the horizontal menu when I press the MENU key:</p>
  
  <pre><code>abstract class MenuScreen extends MainScreen {
  boolean mMenuEnabled = false;
  CyclicHFManager mMenuManager = null;
  
  public MenuScreen() {
      mMenuManager = new CyclicHFManager();
      mMenuManager.setBorder(BorderFactory.createBevelBorder(new XYEdges(4,
              0, 0, 0), new XYEdges(Color.DARKBLUE, 0, 0, 0), new XYEdges(
              Color.WHITE, 0, 0, 0)));
      mMenuManager.setBackground(BackgroundFactory
              .createLinearGradientBackground(Color.DARKBLUE, Color.DARKBLUE,
                      Color.LIGHTBLUE, Color.LIGHTBLUE));
  
  
      for (int i = 0; i &lt; 10; i++) {
          Bitmap nBitmap = new Bitmap(60, 60);
          Graphics g = new Graphics(nBitmap);
          g.setColor(Color.DARKBLUE);
          g.fillRect(0, 0, 60, 60);
          g.setColor(Color.WHITE);
          g.drawRect(0, 0, 60, 60);
          Font f = g.getFont().derive(Font.BOLD, 40);
          g.setFont(f);
          String text = String.valueOf(i);
          g.drawText(text, (60 - f.getAdvance(text)) &gt;&gt; 1, (60 - f
                  .getHeight()) &gt;&gt; 1);
  
          Bitmap fBitmap = new Bitmap(60, 60);
          g = new Graphics(fBitmap);
          g.setColor(Color.DARKBLUE);
          g.fillRect(0, 0, 60, 60);
          g.setColor(Color.GOLD);
          g.drawRect(0, 0, 60, 60);
          g.setFont(f);
          g.drawText(text, (60 - f.getAdvance(text)) &gt;&gt; 1, (60 - f
                  .getHeight()) &gt;&gt; 1);
  
          BitmapButtonField button = new BitmapButtonField(nBitmap, fBitmap);
          button.setCookie(String.valueOf(i));
          button.setPadding(new XYEdges(0, 18, 0, 18));
  
          button.setChangeListener(new FieldChangeListener() {
              public void fieldChanged(Field field, int context) {
                  Dialog.inform("Button # " + (String) field.getCookie());
              }
          });
  
          mMenuManager.add(button);
      }
  }
  
  protected boolean keyDown(int keycode, int time) {
      if (Keypad.KEY_MENU == Keypad.key(keycode)) {
          if (mMenuManager.getManager() != null) {
              delete(mMenuManager);
              mMenuManager.mCyclicTurnedOn = false;
          } else {
              add(mMenuManager);
              mMenuManager.getField(2).setFocus();
              mMenuManager.mCyclicTurnedOn = true;
          }
          return true;
      } else {
          return super.keyDown(keycode, time);
      }
  }}
  </code></pre>
  
  <p>And finally my menu manager:</p>
  
  <pre><code>public class CyclicHFManager extends HorizontalFieldManager {
  int mFocusedFieldIndex = 0;
  public boolean mCyclicTurnedOn = false;
  
  public void focusChangeNotify(int arg0) {
      super.focusChangeNotify(arg0);
      if (mCyclicTurnedOn) {
          int focusedFieldIndexNew = getFieldWithFocusIndex();
          if (focusedFieldIndexNew != mFocusedFieldIndex) {
              if (focusedFieldIndexNew - mFocusedFieldIndex &gt; 0)
                  switchField(0, getFieldCount() - 1);
              else
                  switchField(getFieldCount() - 1, 0);
          }
      } else {
          mFocusedFieldIndex = getFieldWithFocusIndex();
      }
  }
  
  private void switchField(int prevIndex, int newIndex) {
      Field field = getField(prevIndex);
      delete(field);
      insert(field, newIndex);
  }}
  </code></pre>
  
  <p>So as it is like this, it is working: when I press the MENU key, the menu appears, i can navigate between buttons, and it disappear when I press again the same key. The only problem is my menu isn't overlaying my map, it pushes the content up. I tried with the menu manager like in your first response, resizing the content manager but it is the same result.</p>
  
  <p>Max gave me the link <a href="https://stackoverflow.com/questions/1497073/blackberry-fields-layout-animation">Blackberry - fields layout animation</a> to do so, but I really don't know how to use it to make it work in my project...</p>
  
  <p>Thank you for your help!</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>This works great, it's what I wanted. However, I still have a problem because I'm under 4.5. So first in the MenuHostManager constructor, I deleted the  </p>
  
  <pre><code>USE_ALL_HEIGHT  
  </code></pre>
  
  <p>and change  </p>
  
  <pre><code>setPositionChild(mMenuManager, 0, 
      Display.getHeight() - mMenuManager.getPreferredHeight());  
  </code></pre>
  
  <p>like this to have the menu at the bottom of the screen. It worked.  </p>
  
  <p>Then, instead of drawing my bitmaps, I did this: </p>
  
  <pre><code>Bitmap nBitmap = EncodedImage.getEncodedImageResource("menu" + 
      i + ".png").getBitmap();
  BitmapButtonField button = new BitmapButtonField(nBitmap, nBitmap);
  </code></pre>
  
  <p>And it worked too (no rollover for now, later). So it is great!<br>
  I also overwrite the Paint method of my CyclicHFManager to have a background color, because I can't use the BorderFactory and BackgroundFactory... My menu bar has a color for now so it's ok.<br>
  Then, because of these 2 classes missing, in my BitmapButtonField I had to delete the 2 setBorder functions that change the borders. And now i have my buttons pretty big like normal buttons with borders...<br>
  How can I make the same effect as the setBorder functions under 4.5? (BTW, setBorder is not working under 4.5 too...).<br>
  Thank you!</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>See the screen with 5.0 with this code:</p>
  
  <pre><code>public BitmapButtonField(Bitmap normal, Bitmap focused) {
      super(CONSUME_CLICK);
      mNormal = normal;
      mFocused = focused;
      mWidth = mNormal.getWidth();
      mHeight = mNormal.getHeight();
      setMargin(0, 0, 0, 0);
      setPadding(0, 0, 0, 0);
      setBorder(BorderFactory
              .createSimpleBorder(new XYEdges(0, 0, 0, 0)));
      setBorder(VISUAL_STATE_ACTIVE, BorderFactory
              .createSimpleBorder(new XYEdges(0, 0, 0, 0)));
  }
  </code></pre>
  
  <p>Screenshot: i45.tinypic.com/4sz85u.jpg</p>
  
  <p>And under 4.5 with the 2 setBorder functions deleted (because not available):</p>
  
  <pre><code>public BitmapButtonField(Bitmap normal, Bitmap focused) {
      super(CONSUME_CLICK);
      mNormal = normal;
      mFocused = focused;
      mWidth = mNormal.getWidth();
      mHeight = mNormal.getHeight();
      setMargin(0, 0, 0, 0);
      setPadding(0, 0, 0, 0);
  }
  </code></pre>
  
  <p>Screenshot: i49.tinypic.com/rartz5.jpg</p>
  
  <p>And I would like the first screenshot under 5.0 but with 4.5!</p>
  
  <p><strong>UPDATE 3</strong></p>
  
  <p>I solved the problem by adding</p>
  
  <pre><code>protected void applyTheme() {
  
  }
  </code></pre>
  
  <p>There are no more borders and it looks great!</p>
  
  <p>I need to focus on my rollover now, then the click action (I have no dialog box when I click on it on the simulator). I also succeed changing the background of my menu manager, I draw a picture because I can't use BackgroundFactory.createLinearGradientBackground.</p>
  
  <p>How can I manage my rollover when you do have the getVisualState() function?</p>
  
  <p><strong>UPDATE 4</strong></p>
  
  <p>I change the BitmapButtonField a bit to make it rollover without using getVisualState(). I don't know if it's really good to do that, but it is working (I used a temp bitmap mCurrent):</p>
  
  <pre><code>public class BitmapButtonField extends ButtonField {
  Bitmap mNormal;
  Bitmap mFocused;
  Bitmap mCurrent;
  
  int mWidth;
  int mHeight;
  
  public BitmapButtonField(Bitmap normal, Bitmap focused) {
      super(CONSUME_CLICK);
      mNormal = normal;
      mFocused = focused;
      mCurrent = normal;
      mWidth = mNormal.getWidth();
      mHeight = mNormal.getHeight();
      setMargin(0, 0, 0, 0);
      setPadding(0, 0, 0, 0);
  }
  
  protected void onFocus(int direction) {
      mCurrent = mFocused;  
      invalidate();
  }
  
  protected void onUnfocus() {
      mCurrent = mNormal;
      invalidate();
  }
  
  protected void paint(Graphics graphics) {
      Bitmap bitmap = mCurrent;   
      graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(),
              bitmap, 0, 0);
  }
  
  protected void applyTheme() {
  
  }
  
  public int getPreferredWidth() {
      return mWidth;
  }
  
  public int getPreferredHeight() {
      return mHeight;
  }
  
  protected void layout(int width, int height) {
      setExtent(mWidth, mHeight);
  }
  }
  </code></pre>
  
  <p><strong>UPDATE 5</strong></p>
  
  <p>I found the solution. My menu is now working! Thank you for your help about everything on this topic! I might open a new topic for the menu itself, because not sure to do a cyclic one (complicated because of different screen size and resolution to be centered and have the icon all the time in the middle.) See below the code in my MapScreen.java</p>
  
  <pre><code>protected boolean navigationMovement(int dx, int dy, int status, int time) {
      if (mMenuHostManager.isActive()) {
          return super.navigationMovement(dx, dy, status, time);
      }
      return mapField.navigationMovement(dx, dy, status, time);
  }
  
  protected boolean navigationClick(int status, int time) {
      if (mMenuHostManager.isActive()) {
          return super.navigationClick(status, time);
      }
      return true;
  }
  
  protected boolean navigationUnclick(int status, int time) {
      if (mMenuHostManager.isActive()) {
          return super.navigationUnclick(status, time);
      }
      return true;
  }
  </code></pre>