/* Copyright (c) 2008 Bluendo S.r.L. * See about.html for details about license. * * $Id: UICombobox.java 1601 2009-06-19 14:09:03Z luca $ */ /** * */ package it.yup.ui; import it.yup.util.ResourceIDs; import it.yup.util.ResourceManager; import java.util.Enumeration; import java.util.Vector; import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; /** * @author luca * */ public class UICombobox extends UILabel { /** * @author luca * */ public class UIComboScreen extends UIScreen { /* * the time stamp of the last key press */ private long sel_last_ts = 0; /* * the key used when moving selection */ private int sel_last_key = -1; /* * The offset of the slected key in the research pattern */ private int sel_key_offset = 0; /* * The offset of the selected key in the research pattern */ private String sel_pattern = ""; private UIPanel mainPanel = new UIPanel(true, true); private ResourceManager rm = ResourceManager.getManager("common", "en"); private UILabel selectLabel = new UILabel(rm.getString( ResourceIDs.STR_SELECT).toUpperCase()); private UILabel cancelLabel = new UILabel(rm.getString( ResourceIDs.STR_CANCEL).toUpperCase()); /** * */ public UIComboScreen(String title) { super(); this.setTitle(title); this.append(mainPanel); this.mainPanel.setMaxHeight(-1); this.setSelectedItem(mainPanel); mainPanel.setModal(true); UIMenu menu = new UIMenu(""); this.setMenu(menu); menu.append(selectLabel); menu.append(cancelLabel); } public void menuAction(UIMenu menu, UIItem c) { if (c == selectLabel) { } else if (c == cancelLabel) { if (multiChoice == true) { boolean flags[] = new boolean[this.mainPanel.getItems() .size()]; for (int i = 0; i < flags.length; i++) flags[i] = false; setSelectedFlags(flags); } this.sel_pattern = ""; if (this.originalItems != null) { this.updateFilter(); } UICanvas.getInstance().close(this); UICanvas.getInstance().open(UICombobox.this.screen, true); } } public boolean keyPressed(int key) { if (this.popupList.size() > 0 || (this.getMenu() != null && this.getMenu() .isOpenedState())) { return super.keyPressed(key); } int ga = UICanvas.getInstance().getGameAction(key); switch (key) { case Canvas.KEY_NUM0: case Canvas.KEY_NUM1: case Canvas.KEY_NUM2: case Canvas.KEY_NUM3: case Canvas.KEY_NUM4: case Canvas.KEY_NUM5: case Canvas.KEY_NUM6: case Canvas.KEY_NUM7: case Canvas.KEY_NUM8: case Canvas.KEY_NUM9: int key_num = key - Canvas.KEY_NUM0; long t = System.currentTimeMillis(); if ((key_num != sel_last_key) || t - sel_last_ts > 1000) { // new key sel_last_key = key_num; sel_key_offset = 0; if (sel_pattern.length() == 0) { this.originalItems = new UILabel[this.mainPanel .getItems().size()]; this.mainPanel.getItems().copyInto( this.originalItems); } sel_pattern = sel_pattern + UIUtils.itu_keys[key_num][sel_key_offset]; } else { // shifted key sel_key_offset += 1; if (sel_key_offset >= UIUtils.itu_keys[key_num].length) sel_key_offset = 0; sel_pattern = sel_pattern.substring(0, sel_pattern .length() - 1) + UIUtils.itu_keys[key_num][sel_key_offset]; } sel_last_ts = t; updateFilter(); return true; } // any of the "delete" character if (key == UICanvas.MENU_CANCEL || ga == Canvas.LEFT || key == 8) { if (sel_pattern.length() > 0) { sel_pattern = sel_pattern.substring(0, sel_pattern.length() - 1); this.updateFilter(); return true; } } if (UICanvas.getInstance().hasQwerty()) { if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z') || (key >= '0' && key <= '9')) { if (sel_pattern.length() == 0) { this.originalItems = new UILabel[this.getItemList() .size()]; this.getItemList().copyInto(this.originalItems); } updateFilter(); return true; } } if ((key == UICanvas.MENU_RIGHT || ga == Canvas.FIRE) && (this.selectedIndex >= 0 || UICombobox.this.multiChoice)) { UIItem selItem = this.mainPanel.getSelectedItem(); if (selItem != null) { UICombobox.this.selectedIndex = this.mainPanel.getItems() .indexOf(selItem); } if (UICombobox.this.multiChoice == false) { UICombobox.this.screen.itemAction(UICombobox.this); // when "changing" the filter pattern search the index of items // MAY change this.sel_pattern = ""; if (this.originalItems != null) { this.updateFilter(); this.mainPanel.setSelectedItem(selItem); } UICombobox.this.selectedIndex = this.mainPanel.getItems() .indexOf(selItem); UICanvas.getInstance().close(this); UICanvas.getInstance().open(UICombobox.this.screen, true); this.screen.itemAction(UICombobox.this); } else { if (ga == Canvas.FIRE) { // UICheckbox selectedItem = (UICheckbox) this.itemList // .elementAt(this.selectedIndex); // (selectedItem).setChecked(!selectedItem.isChecked()); super.keyPressed(key); } else { if (UICombobox.this.multiChoice == false) { Enumeration en = UIComboScreen.this.getItemList() .elements(); while (en.hasMoreElements()) { UILabel uil = (UILabel) en.nextElement(); uil.setWrappable(false, width); } } if (this.originalItems != null) { sel_pattern = ""; this.updateFilter(); this.setSelectedItem(selItem); } UICanvas.getInstance().close(this); UICanvas.getInstance().open(UICombobox.this.screen, true); UICombobox.this.screen.itemAction(UICombobox.this); } UICombobox.this.setDirty(true); UICombobox.this.askRepaint(); } return true; } else { boolean retVal = super.keyPressed(key); if (UICombobox.this.multiChoice == false) { for (int i = 0; i < itemList.size(); i++) { UILabel uil = (UILabel) this.mainPanel.getItems() .elementAt(i); if (i != UIComboScreen.this.selectedIndex) { uil.setWrappable(false, width); } else { uil.setWrappable(true, this.getWidth() - 10); } } } this.askRepaint(); return retVal; } } private UILabel[] originalItems; private void updateFilter() { mainPanel.setSelectedIndex(-1); this.firstVisibleIndex = 0; this.lastVisibleIndex = 0; if (sel_pattern.length() > 0) { this.setTitle(UICombobox.this.title.getText() + ": " + sel_pattern); UILabel ithLabel = null; this.mainPanel.removeAllItems(); for (int i = 0; i < originalItems.length; i++) { ithLabel = originalItems[i]; if (ithLabel.getText().toUpperCase().indexOf( this.sel_pattern.toUpperCase()) == 0) { this.mainPanel.addItem(ithLabel); } } } else { this.setTitle(UICombobox.this.title.getText()); this.mainPanel.removeAllItems(); for (int i = 0; i < this.originalItems.length; i++) { this.mainPanel.addItem(this.originalItems[i]); } this.originalItems = null; } this.setDirty(true); this.askRepaint(); } } /** the selected index in the item Vector */ private int selectedIndex = 0; /** the pop-up menu shown when FIRE is pressed on the combo-box */ public UIComboScreen comboScreen = null; private boolean multiChoice = false; protected UILabel title = new UILabel(""); /** Constructor */ public UICombobox(String title, boolean multichoice) { super(UICanvas.getUIImage("/icons/combo.png"), ""); this.focusable = true; this.flip = true; this.multiChoice = multichoice; this.title.setText(title); this.wrappable = false; this.comboScreen = new UIComboScreen(title); this.anchorPoint = Graphics.RIGHT | Graphics.VCENTER; Font f = UIConfig.font_body; Font titleFont = Font .getFont(f.getFace(), Font.STYLE_BOLD, f.getSize()); this.title.setFont(titleFont); this.title.setFocusable(true); this.setBg_color(UIConfig.input_color); this.setFg_color(UIConfig.fg_color); this.setSelectedColor(UIConfig.input_color); //this.title.setBg_color(UIConfig.input_color); this.title.setFg_color(UIConfig.fg_color); this.title.setSelectedColor(UIConfig.bg_color); } public void setSelected(boolean _selected) { this.title.setSelected(_selected); super.setSelected(_selected); } public int getHeight(Graphics g) { // 6 is the number of pixels for the border this.height = super.getHeight(g) + this.title.getHeight(g) + 6; return this.height; } /* * (non-Javadoc) * * @see it.yup.ui.UIItem#paint(javax.microedition.lcdui.Graphics, int, int) */ protected void paint(Graphics g, int w, int h) { if (this.multiChoice == false) { if (this.comboScreen.mainPanel.getItems().size() > 0) this.text = ((UILabel) this.comboScreen.mainPanel .getItems().elementAt(this.selectedIndex)).getText(); } else { this.text = ""; if (this.comboScreen.mainPanel.getItems().size() > 0) { Enumeration en = this.comboScreen.mainPanel.getItems() .elements(); while (en.hasMoreElements()) { Object ithItem = en.nextElement(); if (ithItem instanceof UICheckbox) { UICheckbox uic = (UICheckbox) ithItem; if (uic.isChecked()) this.text += (uic.getText() + " "); } } } } this.height = h; // the computation above is used to compute the correct offset in // drawing int titleHeight = title.getHeight(g); this.title.paint(g, w, titleHeight); g.translate(0, titleHeight); int superHeight = super.getHeight(g); g.setColor(UIConfig.bg_color); g.fillRect(0, 0, w, superHeight + 6); //drawBorder(g, 1, 1, w-2, superHeight+4); drawInput(g, 1, 1, w - 2, superHeight + 4); g.translate(3, 3); super.paint(g, w - 6, superHeight); } public void append(String comboItem) { UIItem uimi = null; if (this.multiChoice == false) { uimi = new UILabel(comboItem); ((UILabel) uimi).setWrappable(true, this.comboScreen.getWidth() - 20); } else { uimi = new UICheckbox(comboItem); } comboScreen.mainPanel.addItem(uimi); uimi.setFocusable(true); } public void append(UILabel comboItem) { comboScreen.mainPanel.addItem(comboItem); comboItem.setWrappable(false, -1); comboItem.setFocusable(true); } public void removeAt(int index) { this.comboScreen.mainPanel.removeItemAt(index); } public void removeAll(){ this.comboScreen.mainPanel.removeAllItems(); } public boolean keyPressed(int key) { int ga = UICanvas.getInstance().getGameAction(key); if (ga == Canvas.FIRE) { openMenu(); return false; } return super.keyPressed(key); } /** * @return */ public void openMenu() { UICanvas.getInstance().open(comboScreen, true); } /** * @return The selected index in the item list. */ public int getSelectedIndex() { return selectedIndex; } public int[] getSelectedIndeces() { Vector tempNumber = new Vector(5); int selNumber = 0; for (Enumeration en = comboScreen.mainPanel.getItems().elements(); en .hasMoreElements();) { Object o = en.nextElement(); if (o instanceof UICheckbox && ((UICheckbox) o).isChecked()) tempNumber .addElement(new Integer(selNumber)); selNumber++; } int[] resInt = new int[tempNumber.size()]; for (int i = 0; i < resInt.length; i++) { resInt[i] = ((Integer) tempNumber.elementAt(i)).intValue(); } return resInt; } public String[] getSelectedStrings() { int[] selIndeces = this.getSelectedIndeces(); String[] resString = new String[selIndeces.length]; for (int i = 0; i < selIndeces.length; i++) { resString[i] = ((UILabel) this.comboScreen.mainPanel.getItems() .elementAt(selIndeces[i])).getText(); } return resString; } /** * Sets the slected index in the list * * @param si * the new selected index */ public void setSelectedIndex(int si) { selectedIndex = si; dirty = true; } /** * Used only for a multichoice combo box: sets selected/deselected flags on * all items * * @param flags * the selected flags */ public void setSelectedFlags(boolean[] flags) { if (!isMultiChoice() || flags == null || flags.length != comboScreen.mainPanel.getItems().size()) { return; } for (int i = 0; i < flags.length; i++) { UICheckbox uic = (UICheckbox) comboScreen.mainPanel.getItems() .elementAt(i); uic.setChecked(flags[i]); } dirty = true; } /** * @return The array of selection flags. */ public boolean[] getSelectedFlags() { boolean[] flags = new boolean[comboScreen.mainPanel.getItems().size()]; if (this.multiChoice) { for (int i = 0; i < flags.length; i++) { UICheckbox uic = (UICheckbox) comboScreen.mainPanel.getItems() .elementAt(i); flags[i] = uic.isChecked(); } } else if (this.selectedIndex >= 0 && comboScreen.mainPanel.getItems().size() > 0) flags[this.selectedIndex] = true; return flags; } public void setDirty(boolean dirty) { super.setDirty(dirty); if (comboScreen != null) this.comboScreen.setDirty(dirty); } /** * @return the multiChoice */ public boolean isMultiChoice() { return multiChoice; } /** * Returns true if the item at the selected index is selected. * * @param idx * The item to check for selection * @return {@code true} it the item is selected. {@code false} if the item * is not selected or idx is not a valid index. */ public boolean isSelected(int idx) { if (idx < 0 || idx > comboScreen.mainPanel.getItems().size()) { return false; } UICheckbox uic = (UICheckbox) comboScreen.mainPanel.getItems() .elementAt(idx); return uic.isChecked(); } /** * Return the selected UIItem within the UIItem itself; usually it is the * UIItem itself but in the subclasses (like UIVLayout) it could one of the * contained object. * * @return */ public UIItem getSelectedItem() { // UICombobox SHOULD not raise any itemAction when it is "clicked" // and it is closed return null; } }