/*
* Copyright © 2013 Nokia Corporation. All rights reserved. Nokia and Nokia
* Connecting People are registered trademarks of Nokia Corporation. Oracle and
* Java are trademarks or registered trademarks of Oracle and/or its affiliates.
* Other product and company names mentioned herein may be trademarks or trade
* names of their respective owners. See LICENSE.TXT for license information.
*/
package com.nokia.example;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.TextField;
import com.nokia.mid.ui.TextEditorListener;
/**
* EditScreen of the application.
*
* EditScreen contains a single line editor for the blog post title and multi
* line editor for blog post contents. There are buttons Publish and Exit. The
* Publish button is disabled by default, it is enabled when some content is
* entered into the post content TextEditor.
*
* This class implements view logic of the post editing screen (it creates and
* lays out controls, handles their enabling and traversal).
*
* Support for TextEditors is implemented in base class.
*/
public class EditScreen extends Screen implements TextEditorListener {
private CanvasTextBox titleTextBox;
private CanvasTextBox contentTextBox;
private Button exitButton;
private Button publishButton;
private final int maximumTextLength = 32768;
EditScreen(Display display) {
super(display);
this.titleTextBox = new CanvasTextBox(this, "Title", TextField.ANY,
this.maximumTextLength);
this.titleTextBox.setTextEditorListener(this);
if (!BlogWriter.isFullTouch() && !BlogWriter.isAshaPlatform()) {
this.titleTextBox.setFocused(true);
}
this.contentTextBox = new CanvasTextBox(this, "Post", TextField.ANY,
this.maximumTextLength, true);
this.contentTextBox.setTextEditorListener(this);
try {
this.exitButton = new Button(this, "Exit", new Runnable() {
public void run() {
// When Exit is tapped, close the application
removeItems();
Display.getDisplay(parent).setCurrent(null);
parent.notifyDestroyed();
}
});
this.publishButton = new Button(this, "Publish", new Runnable() {
public void run() {
// Show alert when the Publish button is tapped
parentDisplay.setCurrent(new Alert("Publish",
"Post published successfully.", null,
AlertType.INFO));
}
});
this.publishButton.setEnabled(false);
} catch (Exception ex) {
this.parentDisplay.setCurrent(new Alert("Cannot create controls."),
this);
}
// Set default position of items and buttons
this.layoutControls();
this.titleTextBox.setVisible(true);
this.contentTextBox.setVisible(true);
}
public void pointerPressed(int x, int y) {
// Only very basic pointer handling here
boolean wasContentTextBoxFocused = this.contentTextBox.isFocused();
// TextBoxes set/reset their focus based on pointer event
// The change in event delivery order is needed to keep the virtual keyboard
// open on focus change (first new focus must be given before previous
// focus is lost).
if (this.titleTextBox.isFocused()) {
this.contentTextBox.handlePointerPressed(x, y);
this.titleTextBox.handlePointerPressed(x, y);
} else {
this.contentTextBox.handlePointerPressed(x, y);
this.titleTextBox.handlePointerPressed(x, y);
}
if (this.keyboardOpen) {
// When the keyboard is opened, and content Textbox gains focus,
// we want to change layout
if (!wasContentTextBoxFocused && this.contentTextBox.isFocused()) {
this.layoutControls();
}
}
// Let buttons handle pointerPressed events
this.publishButton.handlePointerEvent(x, y);
this.exitButton.handlePointerEvent(x, y);
}
public void pointerReleased(int x, int y) {
this.contentTextBox.handlePointerReleased(x, y);
this.titleTextBox.handlePointerReleased(x, y);
// Buttons need also pointerReleased events
this.publishButton.handlePointerEvent(x, y);
this.exitButton.handlePointerEvent(x, y);
}
protected void handleEditorTraversal() {
if (this.titleTextBox.isFocused() && this.contentTextBox.isEnabled()) {
this.titleTextBox.setFocused(false);
this.contentTextBox.setFocused(true);
} else if (contentTextBox.isFocused()) {
this.contentTextBox.setFocused(false);
this.titleTextBox.setFocused(true);
}
}
/**
*
*/
private void handleKeyboardState() {
int margin = 5;
int controlPadding = 10;
int controlY = margin;
int textBoxX = margin;
if (this.keyboardOpen && contentTextBox.isFocused()) {
this.titleTextBox.setVisible(false);
this.contentTextBox.setPosition(textBoxX, controlY);
} else {
this.titleTextBox.setVisible(true);
this.titleTextBox.setPosition(textBoxX, controlY);
controlY += this.titleTextBox.getHeight() + controlPadding;
this.contentTextBox.setPosition(textBoxX, controlY);
}
}
/**
* This method lays out controls on the screen.
*
* Layout for portrait and landscape is basically the same (TextEditors use
* as much of the screen as possible), but there are two layouts for the
* situation when virtual keyboard is opened. When the title TextEditor is
* focused, both title and post content editors are visible. When the user
* selects content editor, it uses all the available screen space.
*/
protected void layoutControls() {
if (this.publishButton == null || this.exitButton == null) {
// SizeChanged of the Canvas can be called before constructor
// finishes. It this is that case, we are not ready for layout yet.
return;
}
int margin = 5;
int controlPadding = 10;
int controlY = margin;
// Move controls out of the screen to improve appearance during
// repainting
this.publishButton.setPosition(0, this.getHeight());
this.exitButton.setPosition(0, this.getHeight());
this.titleTextBox.setPosition(0, this.getHeight());
this.contentTextBox.setPosition(0, this.getHeight());
int textBoxX = margin;
// Let text boxes to use full width of the screen
int textEditorWidth = this.getWidth() - 2 * margin;
// Different layouts is used when keyboard is opened
if (!this.keyboardOpen) {
// No keyboard layout
this.titleTextBox.setPosition(textBoxX, controlY);
this.titleTextBox.setSize(textEditorWidth, this.titleTextBox.getHeight() + ((BlogWriter.isAshaPlatform()) ? (4 * controlPadding) : 0) );
controlY += this.titleTextBox.getHeight() + controlPadding;
this.contentTextBox.setPosition(textBoxX, controlY);
this.contentTextBox.setSize(textEditorWidth, this.getHeight()
- controlY - this.publishButton.getHeight() - 2
* controlPadding);
} else {
if (this.titleTextBox.isFocused()) {
// When title TextBox is focused, show both title and post text
// boxes
this.titleTextBox.setSize(textEditorWidth, this.titleTextBox.getHeight());
this.titleTextBox.setPosition(textBoxX, controlY);
controlY += this.titleTextBox.getHeight() + controlPadding;
this.contentTextBox.setSize(textEditorWidth, this.getHeight()
- controlY - controlPadding);
this.contentTextBox.setPosition(textBoxX, controlY);
} else if (this.contentTextBox.isFocused()) {
// Move the title TextEditor out of screen to make more space for
// post content when it is focused
this.titleTextBox.setPosition(textBoxX, -this.titleTextBox.getHeight());
this.contentTextBox.setSize(textEditorWidth, this.getHeight()
- controlY - controlPadding);
this.contentTextBox.setPosition(textBoxX, controlY);
}
}
// Calculate width of the Button based on available area
int buttonWidth = (2 * this.getWidth()) / 5;
publishButton.setSize(buttonWidth, publishButton.getHeight());
exitButton.setSize(buttonWidth, exitButton.getHeight());
// Buttons have maximum and minimum width. Get it to compute position
// properly.
buttonWidth = publishButton.getWidth();
// Place Buttons in one row under text boxes
int buttonX = (this.getWidth() / 2 - buttonWidth) / 2;
controlY += this.contentTextBox.getHeight() + controlPadding;
this.publishButton.setPosition(buttonX, controlY);
this.exitButton.setPosition(buttonX + this.getWidth() / 2, controlY);
// Update last width used for layout. Used for orientation change
// detection.
this.lastWidth = this.getWidth();
}
public void removeItems() {
this.titleTextBox.dispose();
this.contentTextBox.dispose();
this.publishButton.dispose();
this.exitButton.dispose();
}
protected void enableControls() {
boolean enabled = !this.keyboardOpen;
boolean publishEnabled = enabled;
if (enabled) {
if (contentTextBox.isEmpty()) {
// No content - disable Publish button
publishEnabled = false;
}
}
this.publishButton.setEnabled(publishEnabled);
this.exitButton.setEnabled(true);
}
public void displayOrientationChanged(int arg0) {
// TODO Auto-generated method stub
}
public void showNotify(int keyboardCategory) {
if (BlogWriter.isFullTouch() || BlogWriter.isAshaPlatform()) {
this.keyboardOpen = true;
this.handleKeyboardState();
this.enableControls();
}
}
public void hideNotify(int keyboardCategory) {
if (BlogWriter.isFullTouch() || BlogWriter.isAshaPlatform()) {
this.keyboardOpen = false;
this.handleKeyboardState();
this.enableControls();
}
}
}