/* * GraphForm.java * * Created on 3 Ноябрь 2010 г., 11:44 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package jimmui.view.form; import jimmui.view.base.touch.*; import jimmui.view.text.*; import java.util.Vector; import javax.microedition.lcdui.*; import jimm.comm.*; import jimm.modules.*; import jimmui.view.*; import jimmui.view.base.*; import jimmui.view.menu.*; import jimm.util.JLocale; /** * * @author Vladimir Kryukov */ public final class GraphForm extends VirtualList implements TextBoxListener, SelectListener, Form { private Vector<Control> controls = new Vector<Control>(); private InputTextBox box; private Font boldFont; private Font normalFont; private Font[] fontSet; private FormListener formListener; private ControlStateListener controlListener; private static final byte CONTROL_TEXT = 0; private static final byte CONTROL_INPUT = 1; private static final byte CONTROL_CHECKBOX = 2; private static final byte CONTROL_SELECT = 3; private static final byte CONTROL_GAUGE = 4; private static final byte CONTROL_IMAGE = 5; private static final byte CONTROL_LINK = 6; private static final byte CONTROL_COLOR = 7; private int OFFSET = 3; private int BOTTOM = 3; public GraphForm(String caption, String ok, String cancel, FormListener l) { super(JLocale.getString(caption)); formListener = l; fontSet = GraphicsEx.contactListFontSet; boldFont = fontSet[FONT_STYLE_BOLD]; normalFont = fontSet[FONT_STYLE_PLAIN]; setMovingPolicy(MP_SELECTABLE_ONLY); setSoftBarLabels(ok, ok, cancel, true); } @Override public void setControlStateListener(ControlStateListener l) { controlListener = l; } protected void doJimmAction(int keyCode) { switch (keyCode) { case NativeCanvas.JIMM_SELECT: onControlSelected(); break; case NativeCanvas.JIMM_MENU: if (null == formListener) { back(); break; } formListener.formAction(this, true); break; case NativeCanvas.JIMM_BACK: if (null == formListener) { back(); break; } formListener.formAction(this, false); break; } } protected void doKeyReaction(int keyCode, int actionCode, int type) { if (KEY_RELEASED != type) { if (key(actionCode)) { return; } } super.doKeyReaction(keyCode, actionCode, type); } // #sijapp cond.if modules_TOUCH is "true"# protected void touchItemTaped(int item, int x, TouchState state) { execJimmAction(NativeCanvas.JIMM_SELECT); if (item != getCurrItem()) { return; } Control c = (Control)controls.elementAt(item); if (c.disabled) { return; } if (CONTROL_GAUGE == c.type) { setGaugeLevel(c, x); } } protected void stylusXMoving(TouchState state) { stylusXMoved(state); } protected void stylusXMoved(TouchState state) { int itemIndex = getItemByCoord(state.y); if (itemIndex < 0) { return; } Control c = (Control)controls.elementAt(itemIndex); if (c.disabled) { return; } if (CONTROL_GAUGE == c.type) { setGaugeLevel(c, state.x); } } private void setGaugeLevel(Control c, int x) { final int cursorBorder = 1; x -= cursorBorder; int gaugeWidth = getWidth() - 2 * (OFFSET + cursorBorder) - scrollerWidth; int sectionWidth = gaugeWidth / 11; c.level = Math.max(0, Math.min((x - OFFSET) / sectionWidth, 10)); invalidate(); } // #sijapp cond.end# @Override public void destroy() { clearForm(); formListener = null; controlListener = null; } //////////////////////////////////////////////////////////////////////////////// private Control create(int controlId, byte type, String label, String desc) { Control c = new Control(); c.id = controlId; c.type = type; if ((null != label) || (null != desc)) { int width = getWidth() - scrollerWidth - OFFSET * 2; if (CONTROL_CHECKBOX == type) { width -= calcIconSize() + OFFSET; } Parser parser = new Parser(fontSet, width); if (null != label) { parser.addText(label, THEME_TEXT, FONT_STYLE_BOLD); parser.doCRLF(); } if (null != desc) { parser.addText(desc, THEME_TEXT, FONT_STYLE_PLAIN); } c.description = parser.getPar(); } return c; } @Override public void clearForm() { setAllToTop(); controls.removeAllElements(); } @Override public void addSelector(int controlId, String label, String items, int index) { String[] all = Util.explode(items, '|'); for (int i = 0; i < all.length; ++i) { all[i] = JLocale.getString(all[i]); } addSelector(controlId, label, all, index); } @Override public void addSelector(int controlId, String label, String[] items, int index) { label = (null == label) ? " " : label; Control c = create(controlId, CONTROL_SELECT, null, JLocale.getString(label)); c.items = items; c.current = index % c.items.length; add(c); } @Override public void addVolumeControl(int controlId, String label, int current) { label = (null == label) ? " " : label; Control c = create(controlId, CONTROL_GAUGE, null, JLocale.getString(label)); c.level = current / 10; add(c); } @Override public void addCheckBox(int controlId, String label, boolean selected) { label = (null == label) ? " " : label; Control c = create(controlId, CONTROL_CHECKBOX, null, JLocale.getString(label)); c.selected = selected; add(c); } @Override public void addHeader(String label) { add(create(-1, CONTROL_TEXT, JLocale.getString(label), null)); } @Override public void addString(String label, String text) { add(create(-1, CONTROL_TEXT, JLocale.getString(label), text)); } @Override public void addString(String text) { addString(null, text); } @Override public void addString(int controlId, String text) { add(create(controlId, CONTROL_TEXT, null, text)); } @Override public void addLink(int controlId, String text) { add(create(controlId, CONTROL_LINK, null, text)); } @Override public void addLatinTextField(int controlId, String label, String text, int size) { addTextField(controlId, label, text, size, TextField.ANY); } @Override public void addTextField(int controlId, String label, String text, int size) { addTextField(controlId, label, text, size, TextField.ANY); } @Override public void addPasswordField(int controlId, String label, String text, int size) { addTextField(controlId, label, text, size, TextField.PASSWORD); } @Override public void addTextField(int controlId, String label, String text, int size, int type) { label = (null == label) ? " " : label; Control c = create(controlId, CONTROL_INPUT, null, JLocale.getString(label)); text = StringUtils.notNull(text); text = (text.length() > size) ? text.substring(0, size) : text; c.text = text; c.inputType = type; c.size = size; if (TextField.UNEDITABLE == type) { c.disabled = true; } add(c); } @Override public void addImage(Image img) { Control c = create(-1, CONTROL_IMAGE, null, null); c.image = img; add(c); } @Override public void remove(int controlId) { try { for (int num = 0; num < controls.size(); ++num) { if (((Control)controls.elementAt(num)).id == controlId) { controls.removeElementAt(num); invalidate(); return; } } } catch (Exception ignored) { } } //////////////////////////////////////////////////////////////////////////////// private Control get(int controlId) { for (int num = 0; num < controls.size(); ++num) { if (((Control)controls.elementAt(num)).id == controlId) { return (Control)controls.elementAt(num); } } return null; } @Override public boolean hasControl(int controlId) { return null != get(controlId); } @Override public void setTextFieldLabel(int controlId, String desc) { Control c = get(controlId); byte type = c.type; if (null != desc) { int width = getWidth() - scrollerWidth; if (CONTROL_CHECKBOX == type) { width -= calcIconSize(); } Parser parser = new Parser(fontSet, width); parser.addText(desc, THEME_TEXT, FONT_STYLE_PLAIN); c.description = parser.getPar(); } c.height = calcControlHeight(c); invalidate(); } @Override public int getGaugeValue(int controlId) { try { return get(controlId).level; } catch (Exception e) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("getGaugeValue", e); // #sijapp cond.end# } return 0; } @Override public int getVolumeValue(int controlId) { return getGaugeValue(controlId) * 10; } @Override public String getTextFieldValue(int controlId) { try { return get(controlId).text; } catch (Exception e) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("getTextFieldValue", e); // #sijapp cond.end# } return null; } @Override public int getSelectorValue(int controlId) { try { return get(controlId).current; } catch (Exception e) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("getSelectorValue", e); // #sijapp cond.end# } return 0; } @Override public String getSelectorString(int controlId) { try { return get(controlId).items[get(controlId).current]; } catch (Exception e) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("getSelectorString", e); // #sijapp cond.end# } return null; } @Override public boolean getCheckBoxValue(int controlId) { try { return get(controlId).selected; } catch (Exception e) { // #sijapp cond.if modules_DEBUGLOG is "true" # DebugLog.panic("getChoiceItemValue", e); // #sijapp cond.end# } return false; } @Override public void addThumbnailImage(Image img) { addImage(Util.createThumbnail(img, getWidth(), getHeight())); } public int getSize() { return controls.size(); } //////////////////////////////////////////////////////////////////////////////// private void controlUpdated(Control c) { if (null != controlListener) { controlListener.controlStateChanged(this, c.id); } invalidate(); } private int calcIconSize() { return fontSet[FONT_STYLE_PLAIN].getHeight(); } private int calcControlHeight(Control c) { int height = (null == c.description) ? 0 : c.description.getHeight(); switch (c.type) { case CONTROL_INPUT: case CONTROL_SELECT: height += normalFont.getHeight() + BOTTOM; break; case CONTROL_GAUGE: height += Math.max(minItemHeight, 3 * calcIconSize()); break; case CONTROL_TEXT: case CONTROL_CHECKBOX: case CONTROL_LINK: height += BOTTOM; break; case CONTROL_IMAGE: height += c.image.getHeight() + 2; break; case CONTROL_COLOR: height += normalFont.getHeight() + BOTTOM; break; } if ((CONTROL_TEXT != c.type) && (CONTROL_IMAGE != c.type)) { height = Math.max(height, minItemHeight); } return height + 2; } private void add(Control c) { c.height = calcControlHeight(c); controls.addElement(c); invalidate(); } protected int getItemHeight(int itemIndex) { return ((Control)controls.elementAt(itemIndex)).height; } protected boolean isItemSelectable(int index) { if ((index < 0) || (controls.size() <= index)) { return false; } byte type = ((Control)controls.elementAt(index)).type; return CONTROL_TEXT != type; } protected boolean isCurrentItemSelectable() { int index = getCurrItem(); byte type = ((Control)controls.elementAt(index)).type; return (CONTROL_TEXT != type); } private void onControlSelected() { Control c = (Control)controls.elementAt(getCurrItem()); if (c.disabled) { return; } switch (c.type) { case CONTROL_CHECKBOX: c.selected = !c.selected; controlUpdated(c); break; case CONTROL_INPUT: box = new InputTextBox().create(c.description.getText(), c.size, c.inputType); box.setTextBoxListener(this); box.setString(c.text); box.show(); break; case CONTROL_SELECT: MenuModel list = new MenuModel(); for (int i = 0; i < c.items.length; ++i) { list.addRawItem(c.items[i], null, i); } list.setDefaultItemCode(c.current); list.setActionListener(this); UIBuilder.createMenu(list).show(); break; case CONTROL_LINK: controlUpdated(c); break; } } private boolean key(int actionCode) { if (controls.isEmpty()) { return false; } Control c = (Control)controls.elementAt(getCurrItem()); if (c.disabled) { return false; } if (CONTROL_GAUGE == c.type) { int level = c.level; if (NativeCanvas.NAVIKEY_LEFT == actionCode) { level--; } else if (NativeCanvas.NAVIKEY_RIGHT == actionCode) { level++; } else { return false; } c.level = Math.max(0, Math.min(level, 10)); controlUpdated(c); return true; } if (CONTROL_SELECT == c.type) { if (NativeCanvas.NAVIKEY_LEFT == actionCode) { c.current = (c.current - 1 + c.items.length) % c.items.length; } else if (NativeCanvas.NAVIKEY_RIGHT == actionCode) { c.current = (c.current + 1) % c.items.length; } else { return false; } controlUpdated(c); return true; } return false; } public void textboxAction(InputTextBox b, boolean ok) { if ((box == b) && ok) { Control c = (Control)controls.elementAt(getCurrItem()); c.text = box.getString(); box = null; controlUpdated(c); restore(); } } public void select(Select select, MenuModel menu, int cmd) { Control c = (Control)controls.elementAt(getCurrItem()); c.current = cmd; controlUpdated(c); select.back(); } private void drawCheckIcon(GraphicsEx g, int x, int y, boolean checked) { int size = calcIconSize() - 4 & ~1; x += 2; y += 2; g.setThemeColor(THEME_FORM_BACK); g.fillRect(x + 1, y + 1, size - 1, size - 1); g.setThemeColor(THEME_FORM_BORDER); g.drawSimpleRect(x, y, size, size); if (checked) { g.setThemeColor(THEME_FORM_BORDER); x += 3; y += 3; size -= 5; g.fillRect(x, y, size, size); } } protected void drawItemData(GraphicsEx g, int index, int x1, int y1, int w, int h, int skip, int to) { Control c = (Control)controls.elementAt(index); h -= BOTTOM; x1 += OFFSET; w -= 2 * OFFSET; if (CONTROL_CHECKBOX == c.type) { int iconSize = calcIconSize(); drawCheckIcon(g, x1, y1, c.selected); x1 += iconSize + OFFSET; } else if (CONTROL_GAUGE == c.type) { int sectionWidth = w / 11; g.setThemeColor(THEME_FORM_TEXT); int hh = h - boldFont.getHeight(); for (int i = 0; i < 11; ++i) { int h2 = Math.max(1, i * hh / 11); g.fillRect(x1 + i * sectionWidth, y1 + h - h2 - 1, sectionWidth, h2); } g.setThemeColor(THEME_FORM_EDIT); for (int i = 0; i < c.level + 1; ++i) { int h2 = Math.max(1, i * hh / 11); g.fillRect(x1 + i * sectionWidth, y1 + h - h2 - 1, sectionWidth, h2); } } int hfont = 0; if (null != c.description) { c.description.paint(fontSet, g, x1, y1, 0, h); hfont += c.description.getHeight(); } if ((CONTROL_INPUT == c.type) || (CONTROL_SELECT == c.type)) { h -= 3; int inputH = h - hfont; g.setThemeColor(THEME_FORM_BORDER); if (CONTROL_SELECT == c.type) { g.drawSelectRect(x1, y1 + hfont, w, inputH, calcIconSize() / 2); } else { g.drawFieldRect(x1, y1 + hfont, w, inputH); } String text = (CONTROL_SELECT == c.type) ? c.items[c.current] : c.text; x1 += OFFSET; w -= 2 * OFFSET; if (!StringUtils.isEmpty(text)) { if (TextField.PASSWORD == c.inputType) { text = "******"; } g.setThemeColor(c.disabled ? THEME_FORM_TEXT : THEME_FORM_EDIT); g.setFont(normalFont); int width = w; if (CONTROL_SELECT == c.type) { width -= calcIconSize() - OFFSET; } g.drawString(text, x1, y1 + hfont, width, normalFont.getHeight()); } } if (CONTROL_IMAGE == c.type) { g.drawImageInCenter(c.image, x1, y1 + hfont, w, c.image.getHeight()); } } }