Skip to content
49 changes: 49 additions & 0 deletions CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ public abstract class CodenameOneImplementation {
*/
private final Rectangle paintDirtyTmpRect = new Rectangle();
private BrowserComponent sharedJavascriptContext;
private Dimension initialWindowSizeHintPercent;

static void setOnCurrentFormChange(Runnable on) {
onCurrentFormChange = on;
Expand Down Expand Up @@ -467,6 +468,54 @@ public int getActualDisplayHeight() {
return getDisplayHeight();
}

/**
* Returns the size of the desktop area hosting the application window when running on a desktop
* platform. Implementations that do not support windows may return {@code null}.
*
* @return the desktop size or {@code null}
*/
public Dimension getDesktopSize() {
return null;
}

/**
* Returns the bounds of the application window when running on a desktop platform.
*
* @return the window bounds, defaults to the current display size
*/
public Rectangle getWindowBounds() {
return new Rectangle(0, 0, getDisplayWidth(), getDisplayHeight());
}

/**
* Requests a resize of the application window when supported by the platform.
*
* @param width the desired window width in pixels
* @param height the desired window height in pixels
*/
public void setWindowSize(int width, int height) {
}

/**
* Stores an optional window size hint (in percent values) for desktop environments. Implementations
* that do not support windows may ignore this value.
*
* @param hint a {@link Dimension} whose width/height represent percentages of the desktop to use for
* the initial window size, or {@code null} to clear a previously stored hint
*/
public void setInitialWindowSizeHintPercent(Dimension hint) {
initialWindowSizeHintPercent = hint;
}

/**
* Returns the optional desktop window size hint provided by the first form.
*
* @return the stored hint or {@code null}
*/
public Dimension getInitialWindowSizeHintPercent() {
return initialWindowSizeHintPercent;
}

/**
* Invoked when an exception occurs on the EDT, allows the implementation to
* take control of the device to produce testing information.
Expand Down
74 changes: 74 additions & 0 deletions CodenameOne/src/com/codename1/ui/CN.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import com.codename1.plugin.PluginSupport;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.events.MessageEvent;
import com.codename1.ui.events.WindowEvent;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.geom.Rectangle;
import com.codename1.ui.plaf.Style;
import com.codename1.util.RunnableWithResultSync;
Expand Down Expand Up @@ -813,6 +815,78 @@ public static boolean isDesktop() {
return Display.impl.isDesktop();
}

/**
* Returns the size of the desktop hosting the application window when running on a desktop platform.
*
* @return the desktop size
*/
public static Dimension getDesktopSize() {
return Display.getInstance().getDesktopSize();
}

/**
* Returns the number of monitors attached to the desktop environment when available.
*
* @return the number of monitors
*/
/**
* Returns the current bounds of the application window when supported by the platform.
*
* @return the window bounds
*/
public static Rectangle getWindowBounds() {
return Display.getInstance().getWindowBounds();
}

/**
* Requests a resize of the application window when supported by the platform.
*
* @param width the desired window width
* @param height the desired window height
*/
public static void setWindowSize(int width, int height) {
Display.getInstance().setWindowSize(width, height);
}

/**
* Returns the initial desktop window size hint provided by the first shown form, when available.
*
* @return the stored hint or {@code null}
*/
public static Dimension getInitialWindowSizeHintPercent() {
return Display.getInstance().getInitialWindowSizeHintPercent();
}

/**
* Sets the initial desktop window size hint (percent of the desktop) that should be used when the
* first form is shown. This is primarily useful for desktop environments where the Codename One
* application is hosted in a window rather than full-screen.
*
* @param hint a {@link Dimension} whose width/height represent percentages of the desktop to use for
* the initial window size, or {@code null} to clear a previously stored hint
*/
public static void setInitialWindowSizeHintPercent(Dimension hint) {
Display.getInstance().setInitialWindowSizeHintPercent(hint);
}

/**
* Adds a listener for window events such as resize or move.
*
* @param l the listener to add
*/
public static void addWindowListener(ActionListener<WindowEvent> l) {
Display.getInstance().addWindowListener(l);
}

/**
* Removes a previously registered window listener.
*
* @param l the listener to remove
*/
public static void removeWindowListener(ActionListener<WindowEvent> l) {
Display.getInstance().removeWindowListener(l);
}

/**
* Returns true if the device has dialing capabilities
*
Expand Down
133 changes: 133 additions & 0 deletions CodenameOne/src/com/codename1/ui/Display.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.events.MessageEvent;
import com.codename1.ui.events.WindowEvent;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.geom.Rectangle;
import com.codename1.ui.plaf.Style;
Expand Down Expand Up @@ -261,6 +262,12 @@ public final class Display extends CN1Constants {
* Indicates that commands should try to add themselves to the native menus
*/
public static final int COMMAND_BEHAVIOR_NATIVE = 10;
/**
* Client property key used on the first shown {@link Form} to indicate the desired initial
* window size as a percentage of the available desktop. The value should be a {@link com.codename1.ui.geom.Dimension}
* whose width and height represent percentages.
*/
public static final String WINDOW_SIZE_HINT_PERCENT = "cn1.windowSizePercent";
static final Display INSTANCE = new Display();
static final Object lock = new Object();
private static final int POINTER_PRESSED = 1;
Expand Down Expand Up @@ -293,6 +300,11 @@ public final class Display extends CN1Constants {
private boolean inNativeUI;
private Runnable bookmark;
private EventDispatcher messageListeners;
private EventDispatcher windowListeners;
/**
* Tracks whether the initial window size hint has already been consumed for the first shown form.
*/
private boolean initialWindowSizeApplied;
private boolean disableInvokeAndBlock;
/**
* Enable Async stack traces. This is disabled by default, but will cause
Expand Down Expand Up @@ -430,6 +442,7 @@ private Display() {
public static void init(Object m) {
if (!INSTANCE.codenameOneRunning) {
INSTANCE.codenameOneRunning = true;
INSTANCE.initialWindowSizeApplied = false;
INSTANCE.pluginSupport = new PluginSupport();
INSTANCE.displayInitTime = System.currentTimeMillis();

Expand Down Expand Up @@ -1648,6 +1661,9 @@ void setCurrentForm(Form newForm) {
} else {
forceShow = true;
}
if (!initialWindowSizeApplied) {
initialWindowSizeApplied = applyInitialWindowSize(newForm);
}
keyRepeatCharged = false;
longPressCharged = false;
longPointerCharged = false;
Expand All @@ -1669,6 +1685,18 @@ void setCurrentForm(Form newForm) {
newForm.onShowCompletedImpl();
}

private boolean applyInitialWindowSize(Form form) {
if (form == null) {
return false;
}
Object hint = form.getClientProperty(WINDOW_SIZE_HINT_PERCENT);
if (!(hint instanceof Dimension)) {
return false;
}
impl.setInitialWindowSizeHintPercent((Dimension) hint);
return true;
}

/**
* Indicates whether a delay should exist between calls to flush graphics during
* transition. In some devices flushGraphics is asynchronious causing it to be
Expand Down Expand Up @@ -2552,6 +2580,63 @@ public int getDisplayHeight() {
return impl.getDisplayHeight();
}

/**
* Returns the size of the desktop hosting the application window when running on a desktop platform.
*
* @return the desktop size or the current display size if not supported
*/
public Dimension getDesktopSize() {
Dimension desktopSize = impl.getDesktopSize();
if (desktopSize != null) {
return desktopSize;
}
return new Dimension(getDisplayWidth(), getDisplayHeight());
}

/**
* Returns the current window bounds when running on a desktop platform.
*
* @return the bounds of the application window
*/
public Rectangle getWindowBounds() {
Rectangle bounds = impl.getWindowBounds();
if (bounds == null) {
return new Rectangle(0, 0, getDisplayWidth(), getDisplayHeight());
}
return bounds;
}

/**
* Requests a resize of the application window when supported by the platform.
*
* @param width the desired window width
* @param height the desired window height
*/
public void setWindowSize(int width, int height) {
impl.setWindowSize(width, height);
}

/**
* Returns the initial desktop window size hint provided by the first shown form, when available.
*
* @return the stored hint or {@code null}
*/
public Dimension getInitialWindowSizeHintPercent() {
return impl.getInitialWindowSizeHintPercent();
}

/**
* Sets the initial desktop window size hint (percent of the desktop) that should be used when the
* first form is shown. This is primarily useful for desktop environments where the Codename One
* application is hosted in a window rather than full-screen.
*
* @param hint a {@link Dimension} whose width/height represent percentages of the desktop to use for
* the initial window size, or {@code null} to clear a previously stored hint
*/
public void setInitialWindowSizeHintPercent(Dimension hint) {
impl.setInitialWindowSizeHintPercent(hint);
}

/**
* Causes the given component to repaint, used internally by Form
*
Expand Down Expand Up @@ -3320,6 +3405,54 @@ public void dispatchMessage(MessageEvent evt) {
}
}

/**
* Adds a listener to receive notifications about native window changes such as resize or movement.
*
* @param l the listener to add
*/
public synchronized void addWindowListener(ActionListener<WindowEvent> l) {
if (windowListeners == null) {
windowListeners = new EventDispatcher();
}
windowListeners.addListener(l);
}

/**
* Removes a previously registered window listener.
*
* @param l the listener to remove
*/
public synchronized void removeWindowListener(ActionListener<WindowEvent> l) {
if (windowListeners != null) {
windowListeners.removeListener(l);
}
}

/**
* Dispatches a window change event to registered listeners. This method is intended to be invoked by
* platform implementations.
*
* @param evt the window event to dispatch
*/
public void fireWindowEvent(WindowEvent evt) {
if (evt == null || windowListeners == null || !windowListeners.hasListeners()) {
return;
}
if (isEdt()) {
windowListeners.fireActionEvent(evt);
} else {
final WindowEvent windowEvent = evt;
callSerially(new Runnable() {
@Override
public void run() {
if (windowListeners != null && windowListeners.hasListeners()) {
windowListeners.fireActionEvent(windowEvent);
}
}
});
}
}

/**
* Returns the property from the underlying platform deployment or the default
* value if no deployment values are supported. This is equivalent to the
Expand Down
Loading
Loading