/******************************************************************************* * Copyright (c) 2011-2012 Nokia Corporation * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Comarch team - initial API and implementation *******************************************************************************/ package org.ned.client.view; import com.sun.lwuit.*; import com.sun.lwuit.animations.CommonTransitions; import com.sun.lwuit.events.ActionEvent; import com.sun.lwuit.events.ActionListener; import com.sun.lwuit.layouts.BorderLayout; import com.sun.lwuit.list.DefaultListModel; import com.sun.lwuit.list.ListModel; import com.sun.lwuit.plaf.Border; import org.ned.client.NedResources; import org.ned.client.view.renderer.MenuCellRenderer; public abstract class ContextMenu { protected Dialog menuDialog = null; protected ListModel optionsModel = null; protected List optionsList = null; protected List mMediaItemList; protected int sizeList; private boolean mIgnoreFirstRelease = false; // fix for issue when menu is activated with long press protected int displayWidth, displayHeight; public ContextMenu( List aList, int size ) { displayWidth = Display.getInstance().getDisplayWidth(); displayHeight = Display.getInstance().getDisplayHeight(); mMediaItemList = aList; sizeList = size; menuDialog = new Dialog(); menuDialog.setAutoDispose( true ); menuDialog.setScrollableY( true ); menuDialog.setScrollableX( false ); menuDialog.setLayout( new BorderLayout() ); optionsList = new List() { public void pointerPressed( int x, int y ) { super.pointerPressed( x, y ); mIgnoreFirstRelease = false; } public void pointerReleased( int x, int y ) { if ( mIgnoreFirstRelease ) { mIgnoreFirstRelease = false; } else { super.pointerReleased( x, y ); } } }; optionsList.getStyle().setBorder( Border.createEmpty() ); optionsList.setFixedSelection( List.FIXED_NONE_CYCLIC ); setTransitions(); buildMenu(); } public void show( int leftMargin, int topMargin ) { mIgnoreFirstRelease = true; leftMargin += 5; // offset to avoid automatic selection of item that shows under the pointer int rightMargin = getHorizontalMargin() - leftMargin; int bottomMargin = getVerticalMargin() - topMargin; if ( bottomMargin < 0 ) { // check if not out off screen bottomMargin = 0; topMargin = getVerticalMargin(); } if ( rightMargin < 0 ) { // check if not out off screen rightMargin = 0; leftMargin = getHorizontalMargin(); } menuDialog.show( topMargin, bottomMargin, leftMargin, rightMargin, true ); } public Dialog getMenuDialog() { return this.menuDialog; } public void setSizeList( int size ) { this.sizeList = size; } protected void buildMenu() { buildOptions(); buildCommands(); } protected abstract void buildOptions(); protected abstract void buildCommands(); protected abstract void action( Command command ); protected final void buildCommands( String[] commands ) { for ( int i = 0; i < commands.length; i++ ) { Command cmd = new Command( commands[i] ); menuDialog.addCommand( cmd ); } menuDialog.addCommandListener( new ActionListener() { public void actionPerformed( ActionEvent evt ) { Command cmd = evt.getCommand(); menuDialog.dispose(); if ( cmd.getCommandName().equals( NedResources.CANCEL ) ) { // do nothing } else { action( (Command)optionsList.getSelectedItem() ); } } } ); menuDialog.addGameKeyListener( Display.GAME_LEFT, new ActionListener() { public void actionPerformed( ActionEvent evt ) { menuDialog.dispose(); } } ); } protected final void buildOptions( Command[] options ) { optionsModel = new DefaultListModel( options ); optionsList.setModel( optionsModel ); optionsList.setRenderer( new MenuCellRenderer() ); optionsList.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent evt ) { if ( evt.getSource() instanceof List ) { menuDialog.dispose(); List list = (List)evt.getSource(); Command cmd = (Command)list.getSelectedItem(); action( cmd ); } } } ); menuDialog.addComponent( BorderLayout.CENTER, optionsList ); } protected void setTransitions() { CommonTransitions ct = CommonTransitions.createSlide( CommonTransitions.SLIDE_HORIZONTAL, true, 600, false ); CommonTransitions ct2 = CommonTransitions.createSlide( CommonTransitions.SLIDE_HORIZONTAL, false, 600, false ); menuDialog.setTransitionInAnimator( ct ); menuDialog.setTransitionOutAnimator( ct2 ); } /** * Calculates available hotizontal space that should be distributed for top and bottom margins * @return hotizontal margin */ protected int getHorizontalMargin() { return (displayWidth - getMenuWidth() < 0 ? 1 : displayWidth - getMenuWidth()); } /** * Calculates available vertical space that should be distributed for top and bottom margins * @return vertical margin */ protected int getVerticalMargin() { int val = displayHeight - getMenuHeight() - Display.getInstance(). getCurrent().getSoftButton( 0 ).getPreferredH(); return (val > 0 ? val : 0); } protected int getMenuHeight() { int height = menuDialog.getStyle().getMargin( Component.BOTTOM ) + menuDialog.getStyle().getMargin( Component.TOP ) + menuDialog.getStyle().getPadding( Component.BOTTOM ) + menuDialog.getStyle().getPadding( Component.TOP ) + menuDialog.getBottomGap() + optionsList.getStyle().getMargin( Component.BOTTOM ) + optionsList.getStyle().getMargin( Component.TOP ) + optionsList.getStyle().getPadding( Component.BOTTOM ) + optionsList.getStyle().getPadding( Component.TOP ) + optionsList.size() * (getSingleOptionHeight() + optionsList. getItemGap()) + optionsList.getBottomGap() + 15; // magic number, could not find all height influencing factors return height; } protected int getSingleOptionHeight() { MenuCellRenderer rendererItem = (MenuCellRenderer)optionsList. getRenderer(); int fontHigh = rendererItem.getStyle().getFont().getHeight();//this font is used in cell int height = fontHigh + rendererItem.getStyle().getPadding( Component.BOTTOM ) + rendererItem.getStyle().getPadding( Component.TOP ) + rendererItem.getStyle().getMargin( Component.BOTTOM ) + rendererItem.getStyle().getMargin( Component.TOP ) + 2 * rendererItem.getStyle().getBorder().getThickness(); return height; } protected int getMenuWidth() { String longestDesc = ""; for ( int i = 0; i < optionsList.size(); i++ ) { String description = ((Command)optionsList.getModel().getItemAt( i )). getCommandName(); longestDesc = description.length() < longestDesc.length() ? longestDesc : description; } MenuCellRenderer rendererItem = (MenuCellRenderer)optionsList. getRenderer(); int selectedWidth = rendererItem.getSelectedStyle().getFont(). stringWidth( longestDesc + " " ); int unselectedWidth = rendererItem.getUnselectedStyle().getFont(). stringWidth( longestDesc + " " ); return optionsList.getStyle().getMargin( Component.LEFT ) + optionsList.getStyle().getMargin( Component.RIGHT ) + optionsList.getStyle().getPadding( Component.LEFT ) + optionsList.getStyle().getPadding( Component.RIGHT ) + menuDialog.getStyle().getMargin( Component.LEFT ) + menuDialog.getStyle().getMargin( Component.RIGHT ) + menuDialog.getStyle().getPadding( Component.LEFT ) + menuDialog.getStyle().getPadding( Component.RIGHT ) + selectedWidth < unselectedWidth ? unselectedWidth : selectedWidth + rendererItem.getStyle().getMargin( Component.LEFT ) + rendererItem.getStyle().getMargin( Component.RIGHT ) + rendererItem.getStyle().getPadding( Component.LEFT ) + rendererItem.getStyle().getPadding( Component.RIGHT ) + optionsList.getSideGap() + 25; // magic number, could not find all height influencing factors } public void show() { show( getHorizontalMargin(), getVerticalMargin() / 2 ); } }