@@ -1,12 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
* <p/>
|
||||
* Copyright 2011 See AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p/>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p/>
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -29,37 +29,44 @@ import com.badlogic.gdx.Preferences;
|
||||
import com.badlogic.gdx.backends.gwt.preloader.Preloader;
|
||||
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderCallback;
|
||||
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderState;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Clipboard;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import com.google.gwt.animation.client.AnimationScheduler;
|
||||
import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback;
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.dom.client.CanvasElement;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
|
||||
import com.google.gwt.user.client.ui.HasVerticalAlignment;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.InlineHTML;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.TextArea;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Implementation of an {@link Application} based on GWT. Clients have to
|
||||
* override {@link #getConfig()} and {@link #getApplicationListener()}. Clients
|
||||
* can override the default loading screen via {@link #getPreloaderCallback()}
|
||||
* and implement any loading screen drawing via GWT widgets.
|
||||
*
|
||||
* @author mzechner
|
||||
*/
|
||||
/** Implementation of an {@link Application} based on GWT. Clients have to override {@link #getConfig()} and
|
||||
* {@link #createApplicationListener()}. Clients can override the default loading screen via
|
||||
* {@link #getPreloaderCallback()} and implement any loading screen drawing via GWT widgets.
|
||||
* @author mzechner */
|
||||
public abstract class GwtApplication implements EntryPoint, Application {
|
||||
private final static Logger log = LoggerFactory.getLogger(GwtApplication.class);
|
||||
|
||||
private ApplicationListener listener;
|
||||
private GwtApplicationConfiguration config;
|
||||
private GwtGraphics graphics;
|
||||
GwtApplicationConfiguration config;
|
||||
GwtGraphics graphics;
|
||||
private GwtInput input;
|
||||
private GwtNet net;
|
||||
private Panel root = null;
|
||||
private TextArea log = null;
|
||||
private int logLevel = LOG_ERROR;
|
||||
private Array<Runnable> runnables = new Array<Runnable>();
|
||||
private Array<Runnable> runnablesHelper = new Array<Runnable>();
|
||||
@@ -69,55 +76,104 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
Preloader preloader;
|
||||
private static AgentInfo agentInfo;
|
||||
private ObjectMap<String, Preferences> prefs = new ObjectMap<String, Preferences>();
|
||||
private Clipboard clipboard;
|
||||
LoadingListener loadingListener;
|
||||
|
||||
/**
|
||||
* @return the configuration for the {@link GwtApplication}.
|
||||
*/
|
||||
public abstract GwtApplicationConfiguration getConfig();
|
||||
/** @return the configuration for the {@link GwtApplication}. */
|
||||
public abstract GwtApplicationConfiguration getConfig ();
|
||||
|
||||
public String getPreloaderBaseURL() {
|
||||
|
||||
public String getPreloaderBaseURL()
|
||||
{
|
||||
return GWT.getHostPageBaseURL() + "assets/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModuleLoad() {
|
||||
public ApplicationListener getApplicationListener() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
public abstract ApplicationListener createApplicationListener();
|
||||
|
||||
@Override
|
||||
public void onModuleLoad () {
|
||||
GwtApplication.agentInfo = computeAgentInfo();
|
||||
this.listener = getApplicationListener();
|
||||
this.listener = createApplicationListener();
|
||||
this.config = getConfig();
|
||||
this.log = config.log;
|
||||
|
||||
addEventListeners();
|
||||
|
||||
if (config.rootPanel != null) {
|
||||
this.root = config.rootPanel;
|
||||
} else {
|
||||
Element element = Document.get().getElementById("embed-" + GWT.getModuleName());
|
||||
if (element == null) {
|
||||
VerticalPanel panel = new VerticalPanel();
|
||||
panel.setWidth("" + config.width + "px");
|
||||
panel.setHeight("" + config.height + "px");
|
||||
panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||
panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
RootPanel.get().add(panel);
|
||||
RootPanel.get().setWidth("" + config.width + "px");
|
||||
RootPanel.get().setHeight("" + config.height + "px");
|
||||
this.root = panel;
|
||||
} else {
|
||||
VerticalPanel panel = new VerticalPanel();
|
||||
panel.setWidth("" + config.width + "px");
|
||||
panel.setHeight("" + config.height + "px");
|
||||
panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||
panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
element.appendChild(panel.getElement());
|
||||
root = panel;
|
||||
}
|
||||
}
|
||||
|
||||
final PreloaderCallback callback = getPreloaderCallback();
|
||||
preloader = createPreloader();
|
||||
preloader.preload("assets.txt", new PreloaderCallback() {
|
||||
@Override
|
||||
public void error(String file) {
|
||||
public void error (String file) {
|
||||
callback.error(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(PreloaderState state) {
|
||||
public void update (PreloaderState state) {
|
||||
callback.update(state);
|
||||
if (state.hasEnded()) {
|
||||
//getRootPanel().clear();
|
||||
getRootPanel().clear();
|
||||
if(loadingListener != null)
|
||||
loadingListener.beforeSetup();
|
||||
setupLoop();
|
||||
if(loadingListener != null)
|
||||
loadingListener.afterSetup();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void setupLoop() {
|
||||
Gdx.app = this;
|
||||
/**
|
||||
* Override this method to return a custom widget informing the that their browser lacks support of WebGL.
|
||||
*
|
||||
* @return Widget to display when WebGL is not supported.
|
||||
*/
|
||||
public Widget getNoWebGLSupportWidget() {
|
||||
return new Label("Sorry, your browser doesn't seem to support WebGL");
|
||||
}
|
||||
|
||||
void setupLoop () {
|
||||
// setup modules
|
||||
try {
|
||||
graphics = new GwtGraphics(null, config);
|
||||
graphics = new GwtGraphics(root, config);
|
||||
} catch (Throwable e) {
|
||||
error("GwtApplication", "exception: " + e.getMessage(), e);
|
||||
//root.clear();
|
||||
//root.add(new Label("Sorry, your browser doesn't seem to support WebGL"));
|
||||
root.clear();
|
||||
root.add(getNoWebGLSupportWidget());
|
||||
return;
|
||||
}
|
||||
lastWidth = graphics.getWidth();
|
||||
lastHeight = graphics.getHeight();
|
||||
Gdx.app = this;
|
||||
Gdx.audio = new GwtAudio();
|
||||
Gdx.graphics = graphics;
|
||||
Gdx.gl20 = graphics.getGL20();
|
||||
Gdx.gl = Gdx.gl20;
|
||||
@@ -126,6 +182,8 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
Gdx.input = this.input;
|
||||
this.net = new GwtNet();
|
||||
Gdx.net = this.net;
|
||||
this.clipboard = new GwtClipboard();
|
||||
updateLogLabelSize();
|
||||
|
||||
// tell listener about app creation
|
||||
try {
|
||||
@@ -137,26 +195,21 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
|
||||
Gdx.gl.glClearColor(1, 1, 1, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
final int frameTime = (int) ((1f / config.fps) * 1000);
|
||||
|
||||
// setup rendering timer
|
||||
new Timer() {
|
||||
AnimationScheduler.get().requestAnimationFrame(new AnimationCallback() {
|
||||
@Override
|
||||
public void run() {
|
||||
public void execute (double timestamp) {
|
||||
try {
|
||||
mainLoop(this, frameTime);
|
||||
mainLoop();
|
||||
} catch (Throwable t) {
|
||||
error("GwtApplication", "exception: " + t.getMessage(), t);
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
AnimationScheduler.get().requestAnimationFrame(this, graphics.canvas);
|
||||
}
|
||||
}.schedule(1);
|
||||
}, graphics.canvas);
|
||||
}
|
||||
|
||||
void mainLoop(Timer timer, int frameTime) {
|
||||
void mainLoop() {
|
||||
graphics.update();
|
||||
if (Gdx.graphics.getWidth() != lastWidth || Gdx.graphics.getHeight() != lastHeight) {
|
||||
GwtApplication.this.listener.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
@@ -170,17 +223,13 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
runnablesHelper.get(i).run();
|
||||
}
|
||||
runnablesHelper.clear();
|
||||
graphics.frameId++;
|
||||
listener.render();
|
||||
input.justTouched = false;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
int diff = (int) (now - graphics.lastTimeStamp);
|
||||
diff = frameTime - diff;
|
||||
timer.schedule(diff > 5 ? diff : 5);
|
||||
input.reset();
|
||||
}
|
||||
|
||||
public Panel getRootPanel() {
|
||||
throw new GdxRuntimeException("no panel!");
|
||||
public Panel getRootPanel () {
|
||||
return root;
|
||||
}
|
||||
|
||||
long loadStart = TimeUtils.nanoTime();
|
||||
@@ -189,27 +238,53 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
return new Preloader(getPreloaderBaseURL());
|
||||
}
|
||||
|
||||
public PreloaderCallback getPreloaderCallback() {
|
||||
return null;
|
||||
public PreloaderCallback getPreloaderCallback () {
|
||||
final Panel preloaderPanel = new VerticalPanel();
|
||||
preloaderPanel.setStyleName("gdx-preloader");
|
||||
final Image logo = new Image(GWT.getModuleBaseURL() + "logo.png");
|
||||
logo.setStyleName("logo");
|
||||
preloaderPanel.add(logo);
|
||||
final Panel meterPanel = new SimplePanel();
|
||||
meterPanel.setStyleName("gdx-meter");
|
||||
meterPanel.addStyleName("red");
|
||||
final InlineHTML meter = new InlineHTML();
|
||||
final Style meterStyle = meter.getElement().getStyle();
|
||||
meterStyle.setWidth(0, Unit.PCT);
|
||||
meterPanel.add(meter);
|
||||
preloaderPanel.add(meterPanel);
|
||||
getRootPanel().add(preloaderPanel);
|
||||
return new PreloaderCallback() {
|
||||
|
||||
@Override
|
||||
public void error (String file) {
|
||||
System.out.println("error: " + file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update (PreloaderState state) {
|
||||
meterStyle.setWidth(100f * state.getProgress(), Unit.PCT);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graphics getGraphics() {
|
||||
public Graphics getGraphics () {
|
||||
return graphics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Audio getAudio() {
|
||||
public Audio getAudio () {
|
||||
return Gdx.audio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Input getInput() {
|
||||
public Input getInput () {
|
||||
return Gdx.input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Files getFiles() {
|
||||
public Files getFiles () {
|
||||
return Gdx.files;
|
||||
}
|
||||
|
||||
@@ -218,37 +293,107 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
return Gdx.net;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String tag, String message) {
|
||||
log.info("{} : {}", tag, message);
|
||||
private void updateLogLabelSize () {
|
||||
if (log != null) {
|
||||
if (graphics != null) {
|
||||
log.setSize(graphics.getWidth() + "px", "200px");
|
||||
} else {
|
||||
log.setSize("400px", "200px"); // Should not happen at this point, use dummy value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkLogLabel () {
|
||||
if (log == null) {
|
||||
log = new TextArea();
|
||||
|
||||
// It's possible that log functions are called
|
||||
// before the app is initialized. E.g. SoundManager can call log functions before the app is initialized.
|
||||
// Since graphics is null, we're getting errors. The log size will be updated later, in case graphics was null
|
||||
if (graphics != null) {
|
||||
log.setSize(graphics.getWidth() + "px", "200px");
|
||||
} else {
|
||||
log.setSize("400px", "200px"); // Dummy value
|
||||
}
|
||||
|
||||
log.setReadOnly(true);
|
||||
root.add(log);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String tag, String message, Throwable exception) {
|
||||
log.info("{} : {}\n{}", tag, exception, getStackTrace(exception));
|
||||
public void log (String tag, String message) {
|
||||
if (logLevel >= LOG_INFO) {
|
||||
checkLogLabel();
|
||||
log.setText(log.getText() + "\n" + tag + ": " + message);
|
||||
log.setCursorPos(log.getText().length() - 1);
|
||||
System.out.println(tag + ": " + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String tag, String message) {
|
||||
log.error("{} : {}", tag, message);
|
||||
public void log (String tag, String message, Throwable exception) {
|
||||
if (logLevel >= LOG_INFO) {
|
||||
checkLogLabel();
|
||||
log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + getMessages(exception) + "\n");
|
||||
log.setCursorPos(log.getText().length() - 1);
|
||||
System.out.println(tag + ": " + message + "\n" + exception.getMessage());
|
||||
System.out.println(getStackTrace(exception));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String tag, String message, Throwable exception) {
|
||||
log.error("{} : {}\n{}", tag, message, getStackTrace(exception));
|
||||
public void error (String tag, String message) {
|
||||
if (logLevel >= LOG_ERROR) {
|
||||
checkLogLabel();
|
||||
log.setText(log.getText() + "\n" + tag + ": " + message + "\n");
|
||||
log.setCursorPos(log.getText().length() - 1);
|
||||
System.err.println(tag + ": " + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String tag, String message) {
|
||||
log.debug("{} : {}", tag, message);
|
||||
public void error (String tag, String message, Throwable exception) {
|
||||
if (logLevel >= LOG_ERROR) {
|
||||
checkLogLabel();
|
||||
log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + getMessages(exception) + "\n");
|
||||
log.setCursorPos(log.getText().length() - 1);
|
||||
System.err.println(tag + ": " + message + "\n" + exception.getMessage() + "\n");
|
||||
System.out.println(getStackTrace(exception));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String tag, String message, Throwable exception) {
|
||||
log.debug("{} : {}\n{}", tag, message, getStackTrace(exception));
|
||||
public void debug (String tag, String message) {
|
||||
if (logLevel >= LOG_DEBUG) {
|
||||
checkLogLabel();
|
||||
log.setText(log.getText() + "\n" + tag + ": " + message + "\n");
|
||||
log.setCursorPos(log.getText().length() - 1);
|
||||
System.out.println(tag + ": " + message + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
private String getStackTrace(Throwable e) {
|
||||
@Override
|
||||
public void debug (String tag, String message, Throwable exception) {
|
||||
if (logLevel >= LOG_DEBUG) {
|
||||
checkLogLabel();
|
||||
log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + getMessages(exception) + "\n");
|
||||
log.setCursorPos(log.getText().length() - 1);
|
||||
System.out.println(tag + ": " + message + "\n" + exception.getMessage());
|
||||
System.out.println(getStackTrace(exception));
|
||||
}
|
||||
}
|
||||
|
||||
private String getMessages (Throwable e) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
while (e != null) {
|
||||
buffer.append(e.getMessage() + "\n");
|
||||
e = e.getCause();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private String getStackTrace (Throwable e) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (StackTraceElement trace : e.getStackTrace()) {
|
||||
buffer.append(trace.toString() + "\n");
|
||||
@@ -257,36 +402,37 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(int logLevel) {
|
||||
public void setLogLevel (int logLevel) {
|
||||
this.logLevel = logLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLogLevel() {
|
||||
return LOG_DEBUG;
|
||||
return logLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationType getType() {
|
||||
public ApplicationType getType () {
|
||||
return ApplicationType.WebGL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
public int getVersion () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getJavaHeap() {
|
||||
public long getJavaHeap () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNativeHeap() {
|
||||
public long getNativeHeap () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Preferences getPreferences(String name) {
|
||||
public Preferences getPreferences (String name) {
|
||||
Preferences pref = prefs.get(name);
|
||||
if (pref == null) {
|
||||
pref = new GwtPreferences(name);
|
||||
@@ -296,115 +442,151 @@ public abstract class GwtApplication implements EntryPoint, Application {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard getClipboard() {
|
||||
return new Clipboard() {
|
||||
@Override
|
||||
public String getContents() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContents(String content) {
|
||||
}
|
||||
};
|
||||
public Clipboard getClipboard () {
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postRunnable(Runnable runnable) {
|
||||
public void postRunnable (Runnable runnable) {
|
||||
runnables.add(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit() {
|
||||
public void exit () {
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains precomputed information on the user-agent. Useful for dealing
|
||||
* with browser and OS behavioral differences. Kindly
|
||||
* borrowed from PlayN
|
||||
*/
|
||||
public static AgentInfo agentInfo() {
|
||||
/** Contains precomputed information on the user-agent. Useful for dealing with browser and OS behavioral differences. Kindly
|
||||
* borrowed from PlayN */
|
||||
public static AgentInfo agentInfo () {
|
||||
return agentInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* kindly borrowed from PlayN
|
||||
**/
|
||||
private static native AgentInfo computeAgentInfo() /*-{
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
return {
|
||||
// browser type flags
|
||||
isFirefox : userAgent.indexOf("firefox") != -1,
|
||||
isChrome : userAgent.indexOf("chrome") != -1,
|
||||
isSafari : userAgent.indexOf("safari") != -1,
|
||||
isOpera : userAgent.indexOf("opera") != -1,
|
||||
isIE : userAgent.indexOf("msie") != -1,
|
||||
// OS type flags
|
||||
isMacOS : userAgent.indexOf("mac") != -1,
|
||||
isLinux : userAgent.indexOf("linux") != -1,
|
||||
isWindows : userAgent.indexOf("win") != -1
|
||||
};
|
||||
}-*/;
|
||||
/** kindly borrowed from PlayN **/
|
||||
private static native AgentInfo computeAgentInfo () /*-{
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
return {
|
||||
// browser type flags
|
||||
isFirefox : userAgent.indexOf("firefox") != -1,
|
||||
isChrome : userAgent.indexOf("chrome") != -1,
|
||||
isSafari : userAgent.indexOf("safari") != -1,
|
||||
isOpera : userAgent.indexOf("opera") != -1,
|
||||
isIE : userAgent.indexOf("msie") != -1,
|
||||
// OS type flags
|
||||
isMacOS : userAgent.indexOf("mac") != -1,
|
||||
isLinux : userAgent.indexOf("linux") != -1,
|
||||
isWindows : userAgent.indexOf("win") != -1
|
||||
};
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* Returned by {@link #agentInfo}. Kindly borrowed from PlayN.
|
||||
*/
|
||||
/** Returned by {@link #agentInfo}. Kindly borrowed from PlayN. */
|
||||
public static class AgentInfo extends JavaScriptObject {
|
||||
public final native boolean isFirefox() /*-{
|
||||
return this.isFirefox;
|
||||
}-*/;
|
||||
public final native boolean isFirefox () /*-{
|
||||
return this.isFirefox;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isChrome() /*-{
|
||||
return this.isChrome;
|
||||
}-*/;
|
||||
public final native boolean isChrome () /*-{
|
||||
return this.isChrome;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isSafari() /*-{
|
||||
return this.isSafari;
|
||||
}-*/;
|
||||
public final native boolean isSafari () /*-{
|
||||
return this.isSafari;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isOpera() /*-{
|
||||
return this.isOpera;
|
||||
}-*/;
|
||||
public final native boolean isOpera () /*-{
|
||||
return this.isOpera;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isIE() /*-{
|
||||
return this.isIE;
|
||||
}-*/;
|
||||
public final native boolean isIE () /*-{
|
||||
return this.isIE;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isMacOS() /*-{
|
||||
return this.isMacOS;
|
||||
}-*/;
|
||||
public final native boolean isMacOS () /*-{
|
||||
return this.isMacOS;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isLinux() /*-{
|
||||
return this.isLinux;
|
||||
}-*/;
|
||||
public final native boolean isLinux () /*-{
|
||||
return this.isLinux;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isWindows() /*-{
|
||||
return this.isWindows;
|
||||
}-*/;
|
||||
public final native boolean isWindows () /*-{
|
||||
return this.isWindows;
|
||||
}-*/;
|
||||
|
||||
protected AgentInfo() {
|
||||
protected AgentInfo () {
|
||||
}
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
public String getBaseUrl () {
|
||||
return preloader.baseUrl;
|
||||
}
|
||||
|
||||
public Preloader getPreloader() {
|
||||
public Preloader getPreloader () {
|
||||
return preloader;
|
||||
}
|
||||
|
||||
public CanvasElement getCanvasElement(){
|
||||
return graphics.canvas;
|
||||
}
|
||||
|
||||
public LoadingListener getLoadingListener () {
|
||||
return loadingListener;
|
||||
}
|
||||
|
||||
public void setLoadingListener (LoadingListener loadingListener) {
|
||||
this.loadingListener = loadingListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLifecycleListener(LifecycleListener listener) {
|
||||
synchronized (lifecycleListeners) {
|
||||
public void addLifecycleListener (LifecycleListener listener) {
|
||||
synchronized(lifecycleListeners) {
|
||||
lifecycleListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLifecycleListener(LifecycleListener listener) {
|
||||
synchronized (lifecycleListeners) {
|
||||
public void removeLifecycleListener (LifecycleListener listener) {
|
||||
synchronized(lifecycleListeners) {
|
||||
lifecycleListeners.removeValue(listener, true);
|
||||
}
|
||||
}
|
||||
|
||||
native static public void consoleLog(String message) /*-{
|
||||
console.log( "GWT: " + message );
|
||||
}-*/;
|
||||
|
||||
private native void addEventListeners () /*-{
|
||||
var self = this;
|
||||
$doc.addEventListener('visibilitychange', function (e) {
|
||||
self.@com.badlogic.gdx.backends.gwt.GwtApplication::onVisibilityChange(Z)($doc['hidden'] !== true);
|
||||
});
|
||||
}-*/;
|
||||
|
||||
private void onVisibilityChange (boolean visible) {
|
||||
if (visible) {
|
||||
for (LifecycleListener listener : lifecycleListeners) {
|
||||
listener.resume();
|
||||
}
|
||||
listener.resume();
|
||||
} else {
|
||||
for (LifecycleListener listener : lifecycleListeners) {
|
||||
listener.pause();
|
||||
}
|
||||
listener.pause();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LoadingListener interface main purpose is to do some things before or after {@link GwtApplication#setupLoop()}
|
||||
*/
|
||||
public interface LoadingListener{
|
||||
/**
|
||||
* Method called before the setup
|
||||
*/
|
||||
public void beforeSetup();
|
||||
|
||||
/**
|
||||
* Method called after the setup
|
||||
*/
|
||||
public void afterSetup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
* <p/>
|
||||
* Copyright 2011 See AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p/>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p/>
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,15 +16,20 @@
|
||||
|
||||
package com.badlogic.gdx.backends.gwt;
|
||||
|
||||
import com.badlogic.gdx.Application;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Graphics;
|
||||
import com.badlogic.gdx.graphics.Cursor;
|
||||
import com.badlogic.gdx.graphics.Cursor.SystemCursor;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.GL30;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.glutils.GLVersion;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.google.gwt.canvas.client.Canvas;
|
||||
import com.google.gwt.dom.client.CanvasElement;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.webgl.client.WebGLContextAttributes;
|
||||
import com.google.gwt.webgl.client.WebGLRenderingContext;
|
||||
@@ -36,20 +41,39 @@ import org.slf4j.LoggerFactory;
|
||||
public class GwtGraphics implements Graphics {
|
||||
static final Logger log = LoggerFactory.getLogger(GwtGraphics.class);
|
||||
|
||||
/* Enum values from http://www.w3.org/TR/screen-orientation. Filtered based on what the browsers actually support. */
|
||||
public enum OrientationLockType {
|
||||
LANDSCAPE("landscape"), PORTRAIT("portrait"), PORTRAIT_PRIMARY("portrait-primary"), PORTRAIT_SECONDARY(
|
||||
"portrait-secondary"), LANDSCAPE_PRIMARY("landscape-primary"), LANDSCAPE_SECONDARY("landscape-secondary");
|
||||
|
||||
private final String name;
|
||||
|
||||
private OrientationLockType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
CanvasElement canvas;
|
||||
WebGLRenderingContext context;
|
||||
GLVersion glVersion;
|
||||
GL20 gl;
|
||||
String extensions;
|
||||
float fps = 0;
|
||||
long lastTimeStamp = System.currentTimeMillis();
|
||||
long frameId = -1;
|
||||
float deltaTime = 0;
|
||||
float time = 0;
|
||||
int frames;
|
||||
GwtApplicationConfiguration config;
|
||||
boolean inFullscreenMode = false;
|
||||
double pixelRatio;
|
||||
|
||||
public GwtGraphics(Panel root, final GwtApplicationConfiguration config) {
|
||||
public GwtGraphics(Panel root, GwtApplicationConfiguration config) {
|
||||
this.pixelRatio = getDevicePixelRatioJSNI();
|
||||
|
||||
if (config.canvasId == null) {
|
||||
@@ -64,10 +88,9 @@ public class GwtGraphics implements Graphics {
|
||||
canvas.setWidth((int) (config.width * pixelRatio));
|
||||
canvas.setHeight((int) (config.height * pixelRatio));
|
||||
|
||||
canvas.getStyle().setWidth(config.width, Unit.PX);
|
||||
canvas.getStyle().setHeight(config.height, Unit.PX);
|
||||
canvas.getStyle().setWidth(config.width, Style.Unit.PX);
|
||||
canvas.getStyle().setHeight(config.height, Style.Unit.PX);
|
||||
}
|
||||
|
||||
this.config = config;
|
||||
|
||||
WebGLContextAttributes attributes = WebGLContextAttributes.create();
|
||||
@@ -75,11 +98,11 @@ public class GwtGraphics implements Graphics {
|
||||
attributes.setStencil(config.stencil);
|
||||
attributes.setAlpha(false);
|
||||
attributes.setPremultipliedAlpha(false);
|
||||
attributes.setPreserveDrawingBuffer(false);
|
||||
|
||||
context = WebGLRenderingContext.getContext(canvas, attributes);
|
||||
if (context == null)
|
||||
throw new GdxRuntimeException("Could not create Canvas for " + attributes);
|
||||
|
||||
context.viewport(0, 0, config.width, config.height);
|
||||
|
||||
// this actually *enables* the option to use std derivatives in shader..
|
||||
@@ -92,6 +115,11 @@ public class GwtGraphics implements Graphics {
|
||||
}
|
||||
|
||||
this.gl = config.useDebugGL ? new GwtGL20Debug(context) : new GdxGL(context);
|
||||
|
||||
String versionString = gl.glGetString(GL20.GL_VERSION);
|
||||
String vendorString = gl.glGetString(GL20.GL_VENDOR);
|
||||
String rendererString = gl.glGetString(GL20.GL_RENDERER);
|
||||
glVersion = new GLVersion(Application.ApplicationType.WebGL, versionString, vendorString, rendererString);
|
||||
}
|
||||
|
||||
public static native double getDevicePixelRatioJSNI() /*-{
|
||||
@@ -125,6 +153,21 @@ public class GwtGraphics implements Graphics {
|
||||
return canvas.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBackBufferWidth() {
|
||||
return canvas.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBackBufferHeight() {
|
||||
return canvas.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFrameId() {
|
||||
return frameId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDeltaTime() {
|
||||
return deltaTime;
|
||||
@@ -140,6 +183,11 @@ public class GwtGraphics implements Graphics {
|
||||
return GraphicsType.WebGL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLVersion getGLVersion() {
|
||||
return glVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPpiX() {
|
||||
return 96;
|
||||
@@ -162,13 +210,28 @@ public class GwtGraphics implements Graphics {
|
||||
|
||||
@Override
|
||||
public boolean supportsDisplayModeChange() {
|
||||
return true;
|
||||
return supportsFullscreenJSNI();
|
||||
}
|
||||
|
||||
private native boolean supportsFullscreenJSNI() /*-{
|
||||
if ("fullscreenEnabled" in $doc) {
|
||||
return $doc.fullscreenEnabled;
|
||||
}
|
||||
if ("webkitFullscreenEnabled" in $doc) {
|
||||
return $doc.webkitFullscreenEnabled;
|
||||
}
|
||||
if ("mozFullScreenEnabled" in $doc) {
|
||||
return $doc.mozFullScreenEnabled;
|
||||
}
|
||||
if ("msFullscreenEnabled" in $doc) {
|
||||
return $doc.msFullscreenEnabled;
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public DisplayMode[] getDisplayModes() {
|
||||
return new DisplayMode[]{new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60,
|
||||
8) {
|
||||
return new DisplayMode[]{new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60, 8) {
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -181,6 +244,21 @@ public class GwtGraphics implements Graphics {
|
||||
}-*/;
|
||||
|
||||
private native boolean isFullscreenJSNI() /*-{
|
||||
// Standards compliant check for fullscreen
|
||||
if ("fullscreenElement" in $doc) {
|
||||
return $doc.fullscreenElement != null;
|
||||
}
|
||||
// Vendor prefixed versions of standard check
|
||||
if ("msFullscreenElement" in $doc) {
|
||||
return $doc.msFullscreenElement != null;
|
||||
}
|
||||
if ("webkitFullscreenElement" in $doc) {
|
||||
return $doc.webkitFullscreenElement != null;
|
||||
}
|
||||
if ("mozFullScreenElement" in $doc) { // Yes, with a capital 'S'
|
||||
return $doc.mozFullScreenElement != null;
|
||||
}
|
||||
// Older, non-standard ways of checking for fullscreen
|
||||
if ("webkitIsFullScreen" in $doc) {
|
||||
return $doc.webkitIsFullScreen;
|
||||
}
|
||||
@@ -194,10 +272,28 @@ public class GwtGraphics implements Graphics {
|
||||
if (!isFullscreen()) {
|
||||
canvas.setWidth(config.width);
|
||||
canvas.setHeight(config.height);
|
||||
if (config.fullscreenOrientation != null) unlockOrientation();
|
||||
} else {
|
||||
/* We just managed to go full-screen. Check if the user has requested a specific orientation. */
|
||||
if (config.fullscreenOrientation != null) lockOrientation(config.fullscreenOrientation);
|
||||
}
|
||||
}
|
||||
|
||||
private native boolean setFullscreenJSNI(GwtGraphics graphics, CanvasElement element) /*-{
|
||||
// Attempt to use the non-prefixed standard API (https://fullscreen.spec.whatwg.org)
|
||||
if (element.requestFullscreen) {
|
||||
element.width = $wnd.screen.width;
|
||||
element.height = $wnd.screen.height;
|
||||
element.requestFullscreen();
|
||||
$doc
|
||||
.addEventListener(
|
||||
"fullscreenchange",
|
||||
function() {
|
||||
graphics.@com.badlogic.gdx.backends.gwt.GwtGraphics::fullscreenChanged()();
|
||||
}, false);
|
||||
return true;
|
||||
}
|
||||
// Attempt to the vendor specific variants of the API
|
||||
if (element.webkitRequestFullScreen) {
|
||||
element.width = $wnd.screen.width;
|
||||
element.height = $wnd.screen.height;
|
||||
@@ -222,46 +318,140 @@ public class GwtGraphics implements Graphics {
|
||||
}, false);
|
||||
return true;
|
||||
}
|
||||
if (element.msRequestFullscreen) {
|
||||
element.width = $wnd.screen.width;
|
||||
element.height = $wnd.screen.height;
|
||||
element.msRequestFullscreen();
|
||||
$doc
|
||||
.addEventListener(
|
||||
"msfullscreenchange",
|
||||
function() {
|
||||
graphics.@com.badlogic.gdx.backends.gwt.GwtGraphics::fullscreenChanged()();
|
||||
}, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}-*/;
|
||||
|
||||
private native void exitFullscreen() /*-{
|
||||
if ($doc.exitFullscreen)
|
||||
$doc.exitFullscreen();
|
||||
if ($doc.msExitFullscreen)
|
||||
$doc.msExitFullscreen();
|
||||
if ($doc.webkitExitFullscreen)
|
||||
$doc.webkitExitFullscreen();
|
||||
if ($doc.mozExitFullscreen)
|
||||
$doc.mozExitFullscreen();
|
||||
if ($doc.webkitCancelFullScreen) // Old WebKit
|
||||
$doc.webkitCancelFullScreen();
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public DisplayMode getDesktopDisplayMode() {
|
||||
public DisplayMode getDisplayMode() {
|
||||
return new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60, 8) {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDisplayMode(DisplayMode displayMode) {
|
||||
if (displayMode.width != getScreenWidthJSNI()
|
||||
&& displayMode.height != getScreenHeightJSNI())
|
||||
public boolean setFullscreenMode(DisplayMode displayMode) {
|
||||
if (displayMode.width != getScreenWidthJSNI() && displayMode.height != getScreenHeightJSNI())
|
||||
return false;
|
||||
return setFullscreenJSNI(this, canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDisplayMode(int width, int height, boolean fullscreen) {
|
||||
if (fullscreen) {
|
||||
if (width != getScreenWidthJSNI() && height != getScreenHeightJSNI())
|
||||
return false;
|
||||
return setFullscreenJSNI(this, canvas);
|
||||
} else {
|
||||
if (isFullscreenJSNI())
|
||||
exitFullscreen();
|
||||
canvas.setWidth(width);
|
||||
canvas.setHeight(height);
|
||||
canvas.getStyle().setWidth(width, Unit.PX);
|
||||
canvas.getStyle().setHeight(height, Unit.PX);
|
||||
public boolean setWindowedMode(int width, int height) {
|
||||
if (isFullscreenJSNI()) exitFullscreen();
|
||||
canvas.setWidth(width);
|
||||
canvas.setHeight(height);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Monitor getPrimaryMonitor() {
|
||||
return new GwtMonitor(0, 0, "Primary Monitor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Monitor getMonitor() {
|
||||
return getPrimaryMonitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Monitor[] getMonitors() {
|
||||
return new Monitor[]{getPrimaryMonitor()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DisplayMode[] getDisplayModes(Monitor monitor) {
|
||||
return getDisplayModes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DisplayMode getDisplayMode(Monitor monitor) {
|
||||
return getDisplayMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to lock the orientation. Typically only supported when in full-screen mode.
|
||||
*
|
||||
* @param orientation the orientation to attempt locking
|
||||
* @return did the locking succeed
|
||||
*/
|
||||
public boolean lockOrientation(OrientationLockType orientation) {
|
||||
return lockOrientationJSNI(orientation.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to unlock the orientation.
|
||||
*
|
||||
* @return did the unlocking succeed
|
||||
*/
|
||||
public boolean unlockOrientation() {
|
||||
return unlockOrientationJSNI();
|
||||
}
|
||||
|
||||
private native boolean lockOrientationJSNI(String orientationEnumValue) /*-{
|
||||
var screen = $wnd.screen;
|
||||
|
||||
// Attempt to find the lockOrientation function
|
||||
screen.gdxLockOrientation = screen.lockOrientation
|
||||
|| screen.mozLockOrientation || screen.msLockOrientation
|
||||
|| screen.webkitLockOrientation;
|
||||
|
||||
if (screen.gdxLockOrientation) {
|
||||
return screen.gdxLockOrientation(orientationEnumValue);
|
||||
}
|
||||
// Actually, the Chrome guys do things a little different for now
|
||||
else if (screen.orientation && screen.orientation.lock) {
|
||||
screen.orientation.lock(orientationEnumValue);
|
||||
// The Chrome API is async, so we can't at this point tell if we succeeded
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
|
||||
private native boolean unlockOrientationJSNI() /*-{
|
||||
var screen = $wnd.screen;
|
||||
|
||||
// Attempt to find the lockOrientation function
|
||||
screen.gdxUnlockOrientation = screen.unlockOrientation
|
||||
|| screen.mozUnlockOrientation || screen.msUnlockOrientation
|
||||
|| screen.webkitUnlockOrientation;
|
||||
|
||||
if (screen.gdxUnlockOrientation) {
|
||||
return screen.gdxUnlockOrientation();
|
||||
}
|
||||
// Actually, the Chrome guys do things a little different for now
|
||||
else if (screen.orientation && screen.orientation.unlock) {
|
||||
screen.orientation.unlock();
|
||||
// The Chrome API is async, so we can't at this point tell if we succeeded
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public BufferFormat getBufferFormat() {
|
||||
@@ -269,10 +459,12 @@ public class GwtGraphics implements Graphics {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExtension(String extension) {
|
||||
if (extensions == null)
|
||||
extensions = Gdx.gl.glGetString(GL20.GL_EXTENSIONS);
|
||||
return extensions.contains(extension);
|
||||
public boolean supportsExtension(String extensionName) {
|
||||
// Contrary to regular OpenGL, WebGL extensions need to be explicitly enabled before they can be used. See
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Using_Extensions
|
||||
// Thus, it is not safe to use an extension just because context.getSupportedExtensions() tells you it is available.
|
||||
// We need to call getExtension() to enable it.
|
||||
return context.getExtension(extensionName) != null;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
@@ -292,6 +484,14 @@ public class GwtGraphics implements Graphics {
|
||||
public void setTitle(String title) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUndecorated(boolean undecorated) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResizable(boolean resizable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVSync(boolean vsync) {
|
||||
}
|
||||
@@ -335,8 +535,23 @@ public class GwtGraphics implements Graphics {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFrameId() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
public Cursor newCursor(Pixmap pixmap, int xHotspot, int yHotspot) {
|
||||
return new GwtCursor(pixmap, xHotspot, yHotspot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursor(Cursor cursor) {
|
||||
((GwtApplication) Gdx.app).graphics.canvas.getStyle().setProperty("cursor", ((GwtCursor) cursor).cssCursorProperty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSystemCursor(SystemCursor systemCursor) {
|
||||
((GwtApplication) Gdx.app).graphics.canvas.getStyle().setProperty("cursor", GwtCursor.getNameForSystemCursor(systemCursor));
|
||||
}
|
||||
|
||||
static class GwtMonitor extends Monitor {
|
||||
protected GwtMonitor(int virtualX, int virtualY, String name) {
|
||||
super(virtualX, virtualY, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See AUTHORS file.
|
||||
* <p/>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p/>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p/>
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -21,28 +21,30 @@ import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.InputProcessor;
|
||||
import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox;
|
||||
import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox.TextInputDialogListener;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.IntSet;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.core.client.JsArray;
|
||||
import com.google.gwt.dom.client.CanvasElement;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.dom.client.Touch;
|
||||
import com.google.gwt.event.dom.client.KeyCodes;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class GwtInput implements Input {
|
||||
static final int MAX_TOUCHES = 20;
|
||||
boolean justTouched = false;
|
||||
private boolean[] touched = new boolean[20];
|
||||
private int[] touchX = new int[20];
|
||||
private int[] touchY = new int[20];
|
||||
private int[] deltaX = new int[20];
|
||||
private int[] deltaY = new int[20];
|
||||
Set<Integer> pressedButtons = new HashSet<Integer>();
|
||||
Set<Integer> pressedKeys = new HashSet<Integer>();
|
||||
private IntMap<Integer> touchMap = new IntMap<Integer>(20);
|
||||
private boolean[] touched = new boolean[MAX_TOUCHES];
|
||||
private int[] touchX = new int[MAX_TOUCHES];
|
||||
private int[] touchY = new int[MAX_TOUCHES];
|
||||
private int[] deltaX = new int[MAX_TOUCHES];
|
||||
private int[] deltaY = new int[MAX_TOUCHES];
|
||||
IntSet pressedButtons = new IntSet();
|
||||
int pressedKeyCount = 0;
|
||||
boolean[] pressedKeys = new boolean[256];
|
||||
boolean keyJustPressed = false;
|
||||
boolean[] justPressedKeys = new boolean[256];
|
||||
InputProcessor processor;
|
||||
char lastKeyCharPressed;
|
||||
float keyRepeatTimer;
|
||||
@@ -50,107 +52,154 @@ public class GwtInput implements Input {
|
||||
final CanvasElement canvas;
|
||||
boolean hasFocus = true;
|
||||
|
||||
public GwtInput(CanvasElement canvas) {
|
||||
public GwtInput (CanvasElement canvas) {
|
||||
this.canvas = canvas;
|
||||
hookEvents();
|
||||
}
|
||||
|
||||
void reset () {
|
||||
justTouched = false;
|
||||
if (keyJustPressed) {
|
||||
keyJustPressed = false;
|
||||
for (int i = 0; i < justPressedKeys.length; i++) {
|
||||
justPressedKeys[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAccelerometerX() {
|
||||
public float getAccelerometerX () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAccelerometerY() {
|
||||
public float getAccelerometerY () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAccelerometerZ() {
|
||||
public float getAccelerometerZ () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
public float getGyroscopeX () {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getGyroscopeY () {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getGyroscopeZ () {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX () {
|
||||
return touchX[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX(int pointer) {
|
||||
public int getX (int pointer) {
|
||||
return touchX[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaX() {
|
||||
public int getDeltaX () {
|
||||
return deltaX[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaX(int pointer) {
|
||||
public int getDeltaX (int pointer) {
|
||||
return deltaX[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
public int getY () {
|
||||
return touchY[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY(int pointer) {
|
||||
public int getY (int pointer) {
|
||||
return touchY[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaY() {
|
||||
public int getDeltaY () {
|
||||
return deltaY[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaY(int pointer) {
|
||||
public int getDeltaY (int pointer) {
|
||||
return deltaY[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTouched() {
|
||||
return touched[0];
|
||||
public boolean isTouched () {
|
||||
for (int pointer = 0; pointer < MAX_TOUCHES; pointer++) {
|
||||
if (touched[pointer]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean justTouched() {
|
||||
public boolean justTouched () {
|
||||
return justTouched;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTouched(int pointer) {
|
||||
public boolean isTouched (int pointer) {
|
||||
return touched[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isButtonPressed(int button) {
|
||||
return button == Buttons.LEFT && touched[0];
|
||||
public boolean isButtonPressed (int button) {
|
||||
return pressedButtons.contains(button) && touched[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyPressed(int key) {
|
||||
if (key == Keys.ANY_KEY)
|
||||
return pressedKeys.size() > 0;
|
||||
return pressedKeys.contains(key);
|
||||
public boolean isKeyPressed (int key) {
|
||||
if (key == Keys.ANY_KEY) {
|
||||
return pressedKeyCount > 0;
|
||||
}
|
||||
if (key < 0 || key > 255) {
|
||||
return false;
|
||||
}
|
||||
return pressedKeys[key];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTextInput(TextInputListener listener, String title, String text) {
|
||||
TextInputDialogBox dialog = new TextInputDialogBox(title, text, null);
|
||||
public boolean isKeyJustPressed (int key) {
|
||||
if (key == Keys.ANY_KEY) {
|
||||
return keyJustPressed;
|
||||
}
|
||||
if (key < 0 || key > 255) {
|
||||
return false;
|
||||
}
|
||||
return justPressedKeys[key];
|
||||
}
|
||||
|
||||
public void getTextInput (TextInputListener listener, String title, String text, String hint) {
|
||||
TextInputDialogBox dialog = new TextInputDialogBox(title, text, hint);
|
||||
final TextInputListener capturedListener = listener;
|
||||
dialog.setListener(new TextInputDialogListener() {
|
||||
@Override
|
||||
public void onPositive(String text) {
|
||||
public void onPositive (String text) {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.input(text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNegative() {
|
||||
public void onNegative () {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.canceled();
|
||||
}
|
||||
@@ -159,208 +208,174 @@ public class GwtInput implements Input {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPlaceholderTextInput(TextInputListener listener, String title, String placeholder) {
|
||||
TextInputDialogBox dialog = new TextInputDialogBox(title, null, placeholder);
|
||||
final TextInputListener capturedListener = listener;
|
||||
dialog.setListener(new TextInputDialogListener() {
|
||||
@Override
|
||||
public void onPositive(String text) {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.input(text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNegative() {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.canceled();
|
||||
}
|
||||
}
|
||||
});
|
||||
public void setOnscreenKeyboardVisible (boolean visible) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnscreenKeyboardVisible(boolean visible) {
|
||||
public void vibrate (int milliseconds) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vibrate(int milliseconds) {
|
||||
public void vibrate (long[] pattern, int repeat) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vibrate(long[] pattern, int repeat) {
|
||||
public void cancelVibrate () {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelVibrate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAzimuth() {
|
||||
public float getAzimuth () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPitch() {
|
||||
public float getPitch () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRoll() {
|
||||
public float getRoll () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getRotationMatrix(float[] matrix) {
|
||||
public void getRotationMatrix (float[] matrix) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentEventTime() {
|
||||
public long getCurrentEventTime () {
|
||||
return currentEventTimeStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCatchBackKey(boolean catchBack) {
|
||||
public void setCatchBackKey (boolean catchBack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCatchMenuKey(boolean catchMenu) {
|
||||
public boolean isCatchBackKey () {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputProcessor(InputProcessor processor) {
|
||||
public void setCatchMenuKey (boolean catchMenu) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCatchMenuKey () {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputProcessor (InputProcessor processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputProcessor getInputProcessor() {
|
||||
public InputProcessor getInputProcessor () {
|
||||
return processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPeripheralAvailable(Peripheral peripheral) {
|
||||
if (peripheral == Peripheral.Accelerometer)
|
||||
return false;
|
||||
if (peripheral == Peripheral.Compass)
|
||||
return false;
|
||||
if (peripheral == Peripheral.HardwareKeyboard)
|
||||
return true;
|
||||
if (peripheral == Peripheral.MultitouchScreen)
|
||||
return isTouchScreen();
|
||||
if (peripheral == Peripheral.OnscreenKeyboard)
|
||||
return false;
|
||||
if (peripheral == Peripheral.Vibrator)
|
||||
return false;
|
||||
public boolean isPeripheralAvailable (Peripheral peripheral) {
|
||||
if (peripheral == Peripheral.Accelerometer) return false;
|
||||
if (peripheral == Peripheral.Compass) return false;
|
||||
if (peripheral == Peripheral.HardwareKeyboard) return true;
|
||||
if (peripheral == Peripheral.MultitouchScreen) return isTouchScreen();
|
||||
if (peripheral == Peripheral.OnscreenKeyboard) return false;
|
||||
if (peripheral == Peripheral.Vibrator) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRotation() {
|
||||
public int getRotation () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Orientation getNativeOrientation() {
|
||||
public Orientation getNativeOrientation () {
|
||||
return Orientation.Landscape;
|
||||
}
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
* @return is Cursor catched
|
||||
*/
|
||||
private native boolean isCursorCatchedJSNI() /*-{
|
||||
if (!navigator.pointer) {
|
||||
navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
|
||||
}
|
||||
if (navigator.pointer) {
|
||||
if (typeof (navigator.pointer.isLocked) === "boolean") {
|
||||
// Chrome initially launched with this interface
|
||||
return navigator.pointer.isLocked;
|
||||
} else if (typeof (navigator.pointer.isLocked) === "function") {
|
||||
// Some older builds might provide isLocked as a function
|
||||
return navigator.pointer.isLocked();
|
||||
} else if (typeof (navigator.pointer.islocked) === "function") {
|
||||
// For compatibility with early Firefox build
|
||||
return navigator.pointer.islocked();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
/** from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
* @return is Cursor catched */
|
||||
private native boolean isCursorCatchedJSNI () /*-{
|
||||
if (!navigator.pointer) {
|
||||
navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
|
||||
}
|
||||
if (navigator.pointer) {
|
||||
if (typeof (navigator.pointer.isLocked) === "boolean") {
|
||||
// Chrome initially launched with this interface
|
||||
return navigator.pointer.isLocked;
|
||||
} else if (typeof (navigator.pointer.isLocked) === "function") {
|
||||
// Some older builds might provide isLocked as a function
|
||||
return navigator.pointer.isLocked();
|
||||
} else if (typeof (navigator.pointer.islocked) === "function") {
|
||||
// For compatibility with early Firefox build
|
||||
return navigator.pointer.islocked();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
* @param element Canvas
|
||||
*/
|
||||
private native void setCursorCatchedJSNI(CanvasElement element) /*-{
|
||||
// Navigator pointer is not the right interface according to spec.
|
||||
// Here for backwards compatibility only
|
||||
if (!navigator.pointer) {
|
||||
navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
|
||||
}
|
||||
// element.requestPointerLock
|
||||
if (!element.requestPointerLock) {
|
||||
element.requestPointerLock = (function() {
|
||||
return element.webkitRequestPointerLock
|
||||
|| element.mozRequestPointerLock || function() {
|
||||
if (navigator.pointer) {
|
||||
navigator.pointer.lock(element);
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
element.requestPointerLock();
|
||||
}-*/;
|
||||
/** from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
* @param element Canvas */
|
||||
private native void setCursorCatchedJSNI (CanvasElement element) /*-{
|
||||
// Navigator pointer is not the right interface according to spec.
|
||||
// Here for backwards compatibility only
|
||||
if (!navigator.pointer) {
|
||||
navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
|
||||
}
|
||||
// element.requestPointerLock
|
||||
if (!element.requestPointerLock) {
|
||||
element.requestPointerLock = (function() {
|
||||
return element.webkitRequestPointerLock
|
||||
|| element.mozRequestPointerLock || function() {
|
||||
if (navigator.pointer) {
|
||||
navigator.pointer.lock(element);
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
element.requestPointerLock();
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*/
|
||||
private native void exitCursorCatchedJSNI() /*-{
|
||||
if (!$doc.exitPointerLock) {
|
||||
$doc.exitPointerLock = (function() {
|
||||
return $doc.webkitExitPointerLock || $doc.mozExitPointerLock
|
||||
|| function() {
|
||||
if (navigator.pointer) {
|
||||
var elem = this;
|
||||
navigator.pointer.unlock();
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
}-*/;
|
||||
/** from https://github.com/toji/game-shim/blob/master/game-shim.js */
|
||||
private native void exitCursorCatchedJSNI () /*-{
|
||||
if (!$doc.exitPointerLock) {
|
||||
$doc.exitPointerLock = (function() {
|
||||
return $doc.webkitExitPointerLock || $doc.mozExitPointerLock
|
||||
|| function() {
|
||||
if (navigator.pointer) {
|
||||
var elem = this;
|
||||
navigator.pointer.unlock();
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
/** from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
* @param event JavaScript Mouse Event
|
||||
* @return movement in x direction
|
||||
*/
|
||||
private native float getMovementXJSNI(NativeEvent event) /*-{
|
||||
return event.movementX || event.webkitMovementX || 0;
|
||||
}-*/;
|
||||
* @return movement in x direction */
|
||||
private native float getMovementXJSNI (NativeEvent event) /*-{
|
||||
return event.movementX || event.webkitMovementX || 0;
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
/** from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
* @param event JavaScript Mouse Event
|
||||
* @return movement in y direction
|
||||
*/
|
||||
private native float getMovementYJSNI(NativeEvent event) /*-{
|
||||
return event.movementY || event.webkitMovementY || 0;
|
||||
}-*/;
|
||||
* @return movement in y direction */
|
||||
private native float getMovementYJSNI (NativeEvent event) /*-{
|
||||
return event.movementY || event.webkitMovementY || 0;
|
||||
}-*/;
|
||||
|
||||
private static native boolean isTouchScreen() /*-{
|
||||
return (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
|
||||
}-*/;
|
||||
private static native boolean isTouchScreen () /*-{
|
||||
return (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* works only for Chrome > Version 18 with enabled Mouse Lock enable in
|
||||
* about:flags or start Chrome with the
|
||||
* --enable-pointer-lock flag
|
||||
*/
|
||||
/** works only for Chrome > Version 18 with enabled Mouse Lock enable in about:flags or start Chrome with the
|
||||
* --enable-pointer-lock flag */
|
||||
@Override
|
||||
public void setCursorCatched(boolean catched) {
|
||||
public void setCursorCatched (boolean catched) {
|
||||
if (catched)
|
||||
setCursorCatchedJSNI(canvas);
|
||||
else
|
||||
@@ -368,89 +383,90 @@ public class GwtInput implements Input {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCursorCatched() {
|
||||
public boolean isCursorCatched () {
|
||||
return isCursorCatchedJSNI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorPosition(int x, int y) {
|
||||
public void setCursorPosition (int x, int y) {
|
||||
// FIXME??
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorImage(Pixmap pixmap, int xHotspot, int yHotspot) {
|
||||
}
|
||||
|
||||
// kindly borrowed from our dear playn friends...
|
||||
static native void addEventListener(JavaScriptObject target, String name, GwtInput handler,
|
||||
boolean capture) /*-{
|
||||
target
|
||||
.addEventListener(
|
||||
name,
|
||||
function(e) {
|
||||
handler.@com.badlogic.gdx.backends.gwt.GwtInput::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e);
|
||||
}, capture);
|
||||
}-*/;
|
||||
static native void addEventListener (JavaScriptObject target, String name, GwtInput handler, boolean capture) /*-{
|
||||
target
|
||||
.addEventListener(
|
||||
name,
|
||||
function(e) {
|
||||
handler.@com.badlogic.gdx.backends.gwt.GwtInput::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e);
|
||||
}, capture);
|
||||
}-*/;
|
||||
|
||||
private static native float getMouseWheelVelocity(NativeEvent evt) /*-{
|
||||
var delta = 0.0;
|
||||
var agentInfo = @com.badlogic.gdx.backends.gwt.GwtApplication::agentInfo()();
|
||||
private static native float getMouseWheelVelocity (NativeEvent evt) /*-{
|
||||
var delta = 0.0;
|
||||
var agentInfo = @com.badlogic.gdx.backends.gwt.GwtApplication::agentInfo()();
|
||||
|
||||
if (agentInfo.isFirefox) {
|
||||
if (agentInfo.isMacOS) {
|
||||
delta = 1.0 * evt.detail;
|
||||
} else {
|
||||
delta = 1.0 * evt.detail / 3;
|
||||
}
|
||||
} else if (agentInfo.isOpera) {
|
||||
if (agentInfo.isLinux) {
|
||||
delta = -1.0 * evt.wheelDelta / 80;
|
||||
} else {
|
||||
// on mac
|
||||
delta = -1.0 * evt.wheelDelta / 40;
|
||||
}
|
||||
} else if (agentInfo.isChrome || agentInfo.isSafari) {
|
||||
delta = -1.0 * evt.wheelDelta / 120;
|
||||
// handle touchpad for chrome
|
||||
if (Math.abs(delta) < 1) {
|
||||
if (agentInfo.isWindows) {
|
||||
delta = -1.0 * evt.wheelDelta;
|
||||
} else if (agentInfo.isMacOS) {
|
||||
delta = -1.0 * evt.wheelDelta / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
return delta;
|
||||
}-*/;
|
||||
if (agentInfo.isFirefox) {
|
||||
if (agentInfo.isMacOS) {
|
||||
delta = 1.0 * evt.detail;
|
||||
} else {
|
||||
delta = 1.0 * evt.detail / 3;
|
||||
}
|
||||
} else if (agentInfo.isOpera) {
|
||||
if (agentInfo.isLinux) {
|
||||
delta = -1.0 * evt.wheelDelta / 80;
|
||||
} else {
|
||||
// on mac
|
||||
delta = -1.0 * evt.wheelDelta / 40;
|
||||
}
|
||||
} else if (agentInfo.isChrome || agentInfo.isSafari) {
|
||||
delta = -1.0 * evt.wheelDelta / 120;
|
||||
// handle touchpad for chrome
|
||||
if (Math.abs(delta) < 1) {
|
||||
if (agentInfo.isWindows) {
|
||||
delta = -1.0 * evt.wheelDelta;
|
||||
} else if (agentInfo.isMacOS) {
|
||||
delta = -1.0 * evt.wheelDelta / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
return delta;
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* Kindly borrowed from PlayN.
|
||||
**/
|
||||
protected static native String getMouseWheelEvent() /*-{
|
||||
if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
|
||||
return "DOMMouseScroll";
|
||||
} else {
|
||||
return "mousewheel";
|
||||
}
|
||||
}-*/;
|
||||
/** Kindly borrowed from PlayN. **/
|
||||
protected static native String getMouseWheelEvent () /*-{
|
||||
if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
|
||||
return "DOMMouseScroll";
|
||||
} else {
|
||||
return "mousewheel";
|
||||
}
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* Kindly borrowed from PlayN.
|
||||
**/
|
||||
protected static float getRelativeX(NativeEvent e, Element target) {
|
||||
return e.getClientX() - target.getAbsoluteLeft() + target.getScrollLeft()
|
||||
+ target.getOwnerDocument().getScrollLeft();
|
||||
/** Kindly borrowed from PlayN. **/
|
||||
protected int getRelativeX (NativeEvent e, CanvasElement target) {
|
||||
float xScaleRatio = target.getWidth() * 1f / target.getClientWidth(); // Correct for canvas CSS scaling
|
||||
return Math.round(xScaleRatio
|
||||
* (e.getClientX() - target.getAbsoluteLeft() + target.getScrollLeft() + target.getOwnerDocument().getScrollLeft()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kindly borrowed from PlayN.
|
||||
**/
|
||||
protected static float getRelativeY(NativeEvent e, Element target) {
|
||||
return e.getClientY() - target.getAbsoluteTop() + target.getScrollTop()
|
||||
+ target.getOwnerDocument().getScrollTop();
|
||||
/** Kindly borrowed from PlayN. **/
|
||||
protected int getRelativeY (NativeEvent e, CanvasElement target) {
|
||||
float yScaleRatio = target.getHeight() * 1f / target.getClientHeight(); // Correct for canvas CSS scaling
|
||||
return Math.round(yScaleRatio
|
||||
* (e.getClientY() - target.getAbsoluteTop() + target.getScrollTop() + target.getOwnerDocument().getScrollTop()));
|
||||
}
|
||||
|
||||
private void hookEvents() {
|
||||
protected int getRelativeX (Touch touch, CanvasElement target) {
|
||||
float xScaleRatio = target.getWidth() * 1f / target.getClientWidth(); // Correct for canvas CSS scaling
|
||||
return Math.round(xScaleRatio * touch.getRelativeX(target));
|
||||
}
|
||||
|
||||
protected int getRelativeY (Touch touch, CanvasElement target) {
|
||||
float yScaleRatio = target.getHeight() * 1f / target.getClientHeight(); // Correct for canvas CSS scaling
|
||||
return Math.round(yScaleRatio * touch.getRelativeY(target));
|
||||
}
|
||||
|
||||
private void hookEvents () {
|
||||
addEventListener(canvas, "mousedown", this, true);
|
||||
// addEventListener(Document.get(), "mousedown", this, true);
|
||||
addEventListener(canvas, "mouseup", this, true);
|
||||
@@ -464,6 +480,7 @@ public class GwtInput implements Input {
|
||||
addEventListener(canvas, "keydown", this, false);
|
||||
addEventListener(canvas, "keyup", this, false);
|
||||
addEventListener(canvas, "keypress", this, false);
|
||||
|
||||
addEventListener(canvas, "touchstart", this, true);
|
||||
addEventListener(canvas, "touchmove", this, true);
|
||||
addEventListener(canvas, "touchcancel", this, true);
|
||||
@@ -471,23 +488,19 @@ public class GwtInput implements Input {
|
||||
|
||||
}
|
||||
|
||||
private int getButton(int button) {
|
||||
if (button == NativeEvent.BUTTON_LEFT)
|
||||
return Buttons.LEFT;
|
||||
if (button == NativeEvent.BUTTON_RIGHT)
|
||||
return Buttons.RIGHT;
|
||||
if (button == NativeEvent.BUTTON_MIDDLE)
|
||||
return Buttons.MIDDLE;
|
||||
private int getButton (int button) {
|
||||
if (button == NativeEvent.BUTTON_LEFT) return Buttons.LEFT;
|
||||
if (button == NativeEvent.BUTTON_RIGHT) return Buttons.RIGHT;
|
||||
if (button == NativeEvent.BUTTON_MIDDLE) return Buttons.MIDDLE;
|
||||
return Buttons.LEFT;
|
||||
}
|
||||
|
||||
private void handleEvent(NativeEvent e) {
|
||||
private void handleEvent (NativeEvent e) {
|
||||
if (e.getType().equals("mousedown")) {
|
||||
if (!e.getEventTarget().equals(canvas) || touched[0]) {
|
||||
float mouseX = (int) getRelativeX(e, canvas);
|
||||
float mouseY = (int) getRelativeY(e, canvas);
|
||||
if (mouseX < 0 || mouseX > Gdx.graphics.getWidth() || mouseY < 0
|
||||
|| mouseY > Gdx.graphics.getHeight()) {
|
||||
float mouseX = getRelativeX(e, canvas);
|
||||
float mouseY = getRelativeY(e, canvas);
|
||||
if (mouseX < 0 || mouseX > Gdx.graphics.getWidth() || mouseY < 0 || mouseY > Gdx.graphics.getHeight()) {
|
||||
hasFocus = false;
|
||||
}
|
||||
return;
|
||||
@@ -502,25 +515,24 @@ public class GwtInput implements Input {
|
||||
this.touchX[0] += getMovementXJSNI(e);
|
||||
this.touchY[0] += getMovementYJSNI(e);
|
||||
} else {
|
||||
this.touchX[0] = (int) getRelativeX(e, canvas);
|
||||
this.touchY[0] = (int) getRelativeY(e, canvas);
|
||||
this.touchX[0] = getRelativeX(e, canvas);
|
||||
this.touchY[0] = getRelativeY(e, canvas);
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
if (processor != null)
|
||||
processor.touchDown(touchX[0], touchY[0], 0, getButton(e.getButton()));
|
||||
if (processor != null) processor.touchDown(touchX[0], touchY[0], 0, getButton(e.getButton()));
|
||||
}
|
||||
|
||||
if (e.getType().equals("mousemove")) {
|
||||
if (isCursorCatched()) {
|
||||
this.deltaX[0] = (int) getMovementXJSNI(e);
|
||||
this.deltaY[0] = (int) getMovementYJSNI(e);
|
||||
this.deltaX[0] = (int)getMovementXJSNI(e);
|
||||
this.deltaY[0] = (int)getMovementYJSNI(e);
|
||||
this.touchX[0] += getMovementXJSNI(e);
|
||||
this.touchY[0] += getMovementYJSNI(e);
|
||||
} else {
|
||||
this.deltaX[0] = (int) getRelativeX(e, canvas) - touchX[0];
|
||||
this.deltaY[0] = (int) getRelativeY(e, canvas) - touchY[0];
|
||||
this.touchX[0] = (int) getRelativeX(e, canvas);
|
||||
this.touchY[0] = (int) getRelativeY(e, canvas);
|
||||
this.deltaX[0] = getRelativeX(e, canvas) - touchX[0];
|
||||
this.deltaY[0] = getRelativeY(e, canvas) - touchY[0];
|
||||
this.touchX[0] = getRelativeX(e, canvas);
|
||||
this.touchY[0] = getRelativeY(e, canvas);
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
if (processor != null) {
|
||||
@@ -532,35 +544,33 @@ public class GwtInput implements Input {
|
||||
}
|
||||
|
||||
if (e.getType().equals("mouseup")) {
|
||||
if (!touched[0])
|
||||
return;
|
||||
if (!touched[0]) return;
|
||||
this.pressedButtons.remove(getButton(e.getButton()));
|
||||
this.touched[0] = pressedButtons.size() > 0;
|
||||
this.touched[0] = pressedButtons.size > 0;
|
||||
if (isCursorCatched()) {
|
||||
this.deltaX[0] = (int) getMovementXJSNI(e);
|
||||
this.deltaY[0] = (int) getMovementYJSNI(e);
|
||||
this.deltaX[0] = (int)getMovementXJSNI(e);
|
||||
this.deltaY[0] = (int)getMovementYJSNI(e);
|
||||
this.touchX[0] += getMovementXJSNI(e);
|
||||
this.touchY[0] += getMovementYJSNI(e);
|
||||
} else {
|
||||
this.deltaX[0] = (int) getRelativeX(e, canvas) - touchX[0];
|
||||
this.deltaY[0] = (int) getRelativeY(e, canvas) - touchY[0];
|
||||
this.touchX[0] = (int) getRelativeX(e, canvas);
|
||||
this.touchY[0] = (int) getRelativeY(e, canvas);
|
||||
this.deltaX[0] = getRelativeX(e, canvas) - touchX[0];
|
||||
this.deltaY[0] = getRelativeY(e, canvas) - touchY[0];
|
||||
this.touchX[0] = getRelativeX(e, canvas);
|
||||
this.touchY[0] = getRelativeY(e, canvas);
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
this.touched[0] = false;
|
||||
if (processor != null)
|
||||
processor.touchUp(touchX[0], touchY[0], 0, getButton(e.getButton()));
|
||||
if (processor != null) processor.touchUp(touchX[0], touchY[0], 0, getButton(e.getButton()));
|
||||
}
|
||||
if (e.getType().equals(getMouseWheelEvent())) {
|
||||
if (processor != null) {
|
||||
processor.scrolled((int) getMouseWheelVelocity(e));
|
||||
processor.scrolled((int)getMouseWheelVelocity(e));
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e.getType().equals("keydown") && hasFocus) {
|
||||
//System.out.println("keydown");
|
||||
// System.out.println("keydown");
|
||||
int code = keyForCode(e.getKeyCode());
|
||||
if (code == 67) {
|
||||
e.preventDefault();
|
||||
@@ -569,23 +579,31 @@ public class GwtInput implements Input {
|
||||
processor.keyTyped('\b');
|
||||
}
|
||||
} else {
|
||||
if (this.pressedKeys.add(code) && processor != null) {
|
||||
processor.keyDown(code);
|
||||
if (!pressedKeys[code]) {
|
||||
pressedKeyCount++;
|
||||
pressedKeys[code] = true;
|
||||
keyJustPressed = true;
|
||||
justPressedKeys[code] = true;
|
||||
if (processor != null) {
|
||||
processor.keyDown(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (e.getType().equals("keypress") && hasFocus) {
|
||||
//System.out.println("keypress");
|
||||
char c = (char) e.getCharCode();
|
||||
if (processor != null)
|
||||
processor.keyTyped(c);
|
||||
// System.out.println("keypress");
|
||||
char c = (char)e.getCharCode();
|
||||
if (processor != null) processor.keyTyped(c);
|
||||
}
|
||||
|
||||
if (e.getType().equals("keyup") && hasFocus) {
|
||||
//System.out.println("keyup");
|
||||
// System.out.println("keyup");
|
||||
int code = keyForCode(e.getKeyCode());
|
||||
this.pressedKeys.remove(code);
|
||||
if (pressedKeys[code]) {
|
||||
pressedKeyCount--;
|
||||
pressedKeys[code] = false;
|
||||
}
|
||||
if (processor != null) {
|
||||
processor.keyUp(code);
|
||||
}
|
||||
@@ -596,10 +614,12 @@ public class GwtInput implements Input {
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
int real = touch.getIdentifier();
|
||||
int touchId;
|
||||
touchMap.put(real, touchId = getAvailablePointer());
|
||||
touched[touchId] = true;
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
touchX[touchId] = getRelativeX(touch, canvas);
|
||||
touchY[touchId] = getRelativeY(touch, canvas);
|
||||
deltaX[touchId] = 0;
|
||||
deltaY[touchId] = 0;
|
||||
if (processor != null) {
|
||||
@@ -613,11 +633,12 @@ public class GwtInput implements Input {
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
|
||||
deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
int real = touch.getIdentifier();
|
||||
int touchId = touchMap.get(real);
|
||||
deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId];
|
||||
deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId];
|
||||
touchX[touchId] = getRelativeX(touch, canvas);
|
||||
touchY[touchId] = getRelativeY(touch, canvas);
|
||||
if (processor != null) {
|
||||
processor.touchDragged(touchX[touchId], touchY[touchId], touchId);
|
||||
}
|
||||
@@ -629,12 +650,14 @@ public class GwtInput implements Input {
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
int real = touch.getIdentifier();
|
||||
int touchId = touchMap.get(real);
|
||||
touchMap.remove(real);
|
||||
touched[touchId] = false;
|
||||
deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
|
||||
deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId];
|
||||
deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId];
|
||||
touchX[touchId] = getRelativeX(touch, canvas);
|
||||
touchY[touchId] = getRelativeY(touch, canvas);
|
||||
if (processor != null) {
|
||||
processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT);
|
||||
}
|
||||
@@ -646,12 +669,14 @@ public class GwtInput implements Input {
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
int real = touch.getIdentifier();
|
||||
int touchId = touchMap.get(real);
|
||||
touchMap.remove(real);
|
||||
touched[touchId] = false;
|
||||
deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
|
||||
deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId];
|
||||
deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId];
|
||||
touchX[touchId] = getRelativeX(touch, canvas);
|
||||
touchY[touchId] = getRelativeY(touch, canvas);
|
||||
if (processor != null) {
|
||||
processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT);
|
||||
}
|
||||
@@ -659,13 +684,18 @@ public class GwtInput implements Input {
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
e.preventDefault();
|
||||
}
|
||||
// if(hasFocus) e.preventDefault();
|
||||
// if(hasFocus) e.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* borrowed from PlayN, thanks guys
|
||||
**/
|
||||
private static int keyForCode(int keyCode) {
|
||||
private int getAvailablePointer () {
|
||||
for (int i = 0; i < MAX_TOUCHES; i++) {
|
||||
if (!touchMap.containsValue(i, false)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** borrowed from PlayN, thanks guys **/
|
||||
private static int keyForCode (int keyCode) {
|
||||
switch (keyCode) {
|
||||
case KeyCodes.KEY_ALT:
|
||||
return Keys.ALT_LEFT;
|
||||
@@ -955,15 +985,4 @@ public class GwtInput implements Input {
|
||||
private static final int KEY_CLOSE_BRACKET = 221;
|
||||
private static final int KEY_SINGLE_QUOTE = 222;
|
||||
|
||||
@Override
|
||||
public boolean isKeyJustPressed(int key) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCatchBackKey() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
* <p/>
|
||||
* Copyright 2011 See AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p/>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p/>
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package com.badlogic.gdx.graphics;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.badlogic.gdx.backends.gwt.GwtFileHandle;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.BufferUtils;
|
||||
@@ -28,38 +33,48 @@ import com.google.gwt.canvas.dom.client.Context2d.Composite;
|
||||
import com.google.gwt.dom.client.CanvasElement;
|
||||
import com.google.gwt.dom.client.ImageElement;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Pixmap implements Disposable {
|
||||
public static Map<Integer, Pixmap> pixmaps = new HashMap<Integer, Pixmap>();
|
||||
static int nextId = 0;
|
||||
|
||||
/**
|
||||
* Different pixel formats.
|
||||
/** Different pixel formats.
|
||||
*
|
||||
* @author mzechner
|
||||
*/
|
||||
* @author mzechner */
|
||||
public enum Format {
|
||||
Alpha, Intensity, LuminanceAlpha, RGB565, RGBA4444, RGB888, RGBA8888;
|
||||
|
||||
public static int toGlFormat (Format format) {
|
||||
if (format == Alpha) return GL20.GL_ALPHA;
|
||||
if (format == Intensity) return GL20.GL_ALPHA;
|
||||
if (format == LuminanceAlpha) return GL20.GL_LUMINANCE_ALPHA;
|
||||
if (format == RGB565) return GL20.GL_RGB;
|
||||
if (format == RGB888) return GL20.GL_RGB;
|
||||
if (format == RGBA4444) return GL20.GL_RGBA;
|
||||
if (format == RGBA8888) return GL20.GL_RGBA;
|
||||
throw new GdxRuntimeException("unknown format: " + format);
|
||||
}
|
||||
|
||||
public static int toGlType (Format format) {
|
||||
if (format == Alpha) return GL20.GL_UNSIGNED_BYTE;
|
||||
if (format == Intensity) return GL20.GL_UNSIGNED_BYTE;
|
||||
if (format == LuminanceAlpha) return GL20.GL_UNSIGNED_BYTE;
|
||||
if (format == RGB565) return GL20.GL_UNSIGNED_SHORT_5_6_5;
|
||||
if (format == RGB888) return GL20.GL_UNSIGNED_BYTE;
|
||||
if (format == RGBA4444) return GL20.GL_UNSIGNED_SHORT_4_4_4_4;
|
||||
if (format == RGBA8888) return GL20.GL_UNSIGNED_BYTE;
|
||||
throw new GdxRuntimeException("unknown format: " + format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blending functions to be set with {@link Pixmap#setBlending}.
|
||||
*
|
||||
* @author mzechner
|
||||
*/
|
||||
/** Blending functions to be set with {@link Pixmap#setBlending}.
|
||||
* @author mzechner */
|
||||
public enum Blending {
|
||||
None, SourceOver
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters to be used with {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
|
||||
/** Filters to be used with {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
|
||||
*
|
||||
* @author mzechner
|
||||
*/
|
||||
* @author mzechner */
|
||||
public enum Filter {
|
||||
NearestNeighbour, BiLinear
|
||||
}
|
||||
@@ -74,128 +89,139 @@ public class Pixmap implements Disposable {
|
||||
int r = 255, g = 255, b = 255;
|
||||
float a;
|
||||
String color = make(r, g, b, a);
|
||||
static String clearColor = make(255, 255, 255, 1.0f);
|
||||
static Blending blending;
|
||||
CanvasPixelArray pixels;
|
||||
private ImageElement imageElement;
|
||||
|
||||
public Pixmap (FileHandle file) {
|
||||
this(((GwtFileHandle)file).preloader.images.get(file.path()));
|
||||
if (imageElement == null) throw new GdxRuntimeException("Couldn't load image '" + file.path() + "', file does not exist");
|
||||
}
|
||||
|
||||
public Context2d getContext() {
|
||||
ensureCanvasExists();
|
||||
return context;
|
||||
}
|
||||
|
||||
public Pixmap(FileHandle file) {
|
||||
GwtFileHandle gwtFile = (GwtFileHandle) file;
|
||||
ImageElement img = gwtFile.preloader.images.get(file.path());
|
||||
if (img == null)
|
||||
throw new GdxRuntimeException("Couldn't load image '" + file.path() + "', file does not exist");
|
||||
create(img.getWidth(), img.getHeight(), Format.RGBA8888);
|
||||
context.setGlobalCompositeOperation(Composite.COPY);
|
||||
context.drawImage(img, 0, 0);
|
||||
context.setGlobalCompositeOperation(getComposite());
|
||||
private static Composite getComposite () {
|
||||
return Composite.SOURCE_OVER;
|
||||
}
|
||||
|
||||
private static Composite getComposite() {
|
||||
return blending == Blending.None ? Composite.COPY : Composite.SOURCE_OVER;
|
||||
public Pixmap (ImageElement img) {
|
||||
this(-1, -1, img);
|
||||
}
|
||||
|
||||
public Pixmap(ImageElement img) {
|
||||
create(img.getWidth(), img.getHeight(), Format.RGBA8888);
|
||||
context.drawImage(img, 0, 0);
|
||||
public Pixmap (int width, int height, Format format) {
|
||||
this(width, height, (ImageElement)null);
|
||||
}
|
||||
|
||||
public Pixmap(int width, int height, Format format) {
|
||||
create(width, height, format);
|
||||
}
|
||||
private Pixmap(int width, int height, ImageElement imageElement) {
|
||||
this.imageElement = imageElement;
|
||||
this.width = imageElement != null ? imageElement.getWidth() : width;
|
||||
this.height = imageElement != null ? imageElement.getHeight() : height;
|
||||
|
||||
private void create(int width, int height, Format format2) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.format = Format.RGBA8888;
|
||||
canvas = Canvas.createIfSupported();
|
||||
canvas.getCanvasElement().setWidth(width);
|
||||
canvas.getCanvasElement().setHeight(height);
|
||||
context = canvas.getContext2d();
|
||||
context.setGlobalCompositeOperation(getComposite());
|
||||
buffer = BufferUtils.newIntBuffer(1);
|
||||
id = nextId++;
|
||||
buffer.put(0, id);
|
||||
pixmaps.put(id, this);
|
||||
}
|
||||
|
||||
public static String make(int r2, int g2, int b2, float a2) {
|
||||
private void create () {
|
||||
canvas = Canvas.createIfSupported();
|
||||
canvas.getCanvasElement().setWidth(width);
|
||||
canvas.getCanvasElement().setHeight(height);
|
||||
context = canvas.getContext2d();
|
||||
context.setGlobalCompositeOperation(getComposite());
|
||||
}
|
||||
|
||||
public static String make (int r2, int g2, int b2, float a2) {
|
||||
return "rgba(" + r2 + "," + g2 + "," + b2 + "," + a2 + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of {@link Blending} to be used for all operations. Default is {@link Blending#SourceOver}.
|
||||
*
|
||||
* @param blending the blending type
|
||||
*/
|
||||
public static void setBlending(Blending blending) {
|
||||
/** Sets the type of {@link Blending} to be used for all operations. Default is {@link Blending#SourceOver}.
|
||||
* @param blending the blending type */
|
||||
public static void setBlending (Blending blending) {
|
||||
Pixmap.blending = blending;
|
||||
Composite composite = getComposite();
|
||||
for (Pixmap pixmap : pixmaps.values()) {
|
||||
pixmap.ensureCanvasExists();
|
||||
pixmap.context.setGlobalCompositeOperation(composite);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the currently set {@link Blending}
|
||||
*/
|
||||
public static Blending getBlending() {
|
||||
/** @return the currently set {@link Blending} */
|
||||
public static Blending getBlending () {
|
||||
return blending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of interpolation {@link Filter} to be used in conjunction with
|
||||
/** Sets the type of interpolation {@link Filter} to be used in conjunction with
|
||||
* {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
|
||||
*
|
||||
* @param filter the filter.
|
||||
*/
|
||||
public static void setFilter(Filter filter) {
|
||||
* @param filter the filter. */
|
||||
public static void setFilter (Filter filter) {
|
||||
}
|
||||
|
||||
public Format getFormat() {
|
||||
public Format getFormat () {
|
||||
return format;
|
||||
}
|
||||
|
||||
public int getGLInternalFormat() {
|
||||
public int getGLInternalFormat () {
|
||||
return GL20.GL_RGBA;
|
||||
}
|
||||
|
||||
public int getGLFormat() {
|
||||
public int getGLFormat () {
|
||||
return GL20.GL_RGBA;
|
||||
}
|
||||
|
||||
public int getGLType() {
|
||||
public int getGLType () {
|
||||
return GL20.GL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
public int getWidth () {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
public int getHeight () {
|
||||
return height;
|
||||
}
|
||||
|
||||
public Buffer getPixels() {
|
||||
public Buffer getPixels () {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
public void dispose () {
|
||||
pixmaps.remove(id);
|
||||
}
|
||||
|
||||
public CanvasElement getCanvasElement() {
|
||||
public CanvasElement getCanvasElement () {
|
||||
ensureCanvasExists();
|
||||
return canvas.getCanvasElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color for the following drawing operations
|
||||
*
|
||||
* @param color the color, encoded as RGBA8888
|
||||
*/
|
||||
public void setColor(int color) {
|
||||
private void ensureCanvasExists () {
|
||||
if (canvas == null) {
|
||||
create();
|
||||
if (imageElement != null) {
|
||||
context.setGlobalCompositeOperation(Composite.COPY);
|
||||
context.drawImage(imageElement, 0, 0);
|
||||
context.setGlobalCompositeOperation(getComposite());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canUseImageElement () {
|
||||
return canvas == null && imageElement != null;
|
||||
}
|
||||
|
||||
public ImageElement getImageElement () {
|
||||
return imageElement;
|
||||
}
|
||||
|
||||
/** Sets the color for the following drawing operations
|
||||
* @param color the color, encoded as RGBA8888 */
|
||||
public void setColor (int color) {
|
||||
ensureCanvasExists();
|
||||
r = (color >>> 24) & 0xff;
|
||||
g = (color >>> 16) & 0xff;
|
||||
b = (color >>> 8) & 0xff;
|
||||
@@ -205,38 +231,34 @@ public class Pixmap implements Disposable {
|
||||
context.setStrokeStyle(this.color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color for the following drawing operations.
|
||||
/** Sets the color for the following drawing operations.
|
||||
*
|
||||
* @param r The red component.
|
||||
* @param g The green component.
|
||||
* @param b The blue component.
|
||||
* @param a The alpha component.
|
||||
*/
|
||||
public void setColor(float r, float g, float b, float a) {
|
||||
this.r = (int) (r * 255);
|
||||
this.g = (int) (g * 255);
|
||||
this.b = (int) (b * 255);
|
||||
* @param a The alpha component. */
|
||||
public void setColor (float r, float g, float b, float a) {
|
||||
ensureCanvasExists();
|
||||
this.r = (int)(r * 255);
|
||||
this.g = (int)(g * 255);
|
||||
this.b = (int)(b * 255);
|
||||
this.a = a;
|
||||
color = make(this.r, this.g, this.b, this.a);
|
||||
context.setFillStyle(color);
|
||||
context.setStrokeStyle(this.color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color for the following drawing operations.
|
||||
*
|
||||
* @param color The color.
|
||||
*/
|
||||
public void setColor(Color color) {
|
||||
/** Sets the color for the following drawing operations.
|
||||
* @param color The color. */
|
||||
public void setColor (Color color) {
|
||||
setColor(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the complete bitmap with the currently set color.
|
||||
*/
|
||||
public void fill() {
|
||||
context.fillRect(0, 0, getWidth(), getHeight());
|
||||
/** Fills the complete bitmap with the currently set color. */
|
||||
public void fill () {
|
||||
ensureCanvasExists();
|
||||
context.clearRect(0, 0, getWidth(), getHeight());
|
||||
rectangle(0, 0, getWidth(), getHeight(), DrawType.FILL);
|
||||
}
|
||||
|
||||
// /**
|
||||
@@ -246,153 +268,117 @@ public class Pixmap implements Disposable {
|
||||
// */
|
||||
// public void setStrokeWidth (int width);
|
||||
|
||||
/**
|
||||
* Draws a line between the given coordinates using the currently set color.
|
||||
/** Draws a line between the given coordinates using the currently set color.
|
||||
*
|
||||
* @param x The x-coodinate of the first point
|
||||
* @param y The y-coordinate of the first point
|
||||
* @param x The x-coodinate of the first point
|
||||
* @param y The y-coordinate of the first point
|
||||
* @param x2 The x-coordinate of the first point
|
||||
* @param y2 The y-coordinate of the first point
|
||||
*/
|
||||
public void drawLine(int x, int y, int x2, int y2) {
|
||||
context.beginPath();
|
||||
context.moveTo(x, y);
|
||||
context.lineTo(x2, y2);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
* @param y2 The y-coordinate of the first point */
|
||||
public void drawLine (int x, int y, int x2, int y2) {
|
||||
line(x, y, x2, y2, DrawType.STROKE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a rectangle outline starting at x, y extending by width to the right and by height downwards (y-axis points downwards)
|
||||
/** Draws a rectangle outline starting at x, y extending by width to the right and by height downwards (y-axis points downwards)
|
||||
* using the current color.
|
||||
*
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param width The width in pixels
|
||||
* @param height The height in pixels
|
||||
*/
|
||||
public void drawRectangle(int x, int y, int width, int height) {
|
||||
context.beginPath();
|
||||
context.rect(x, y, width, height);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param width The width in pixels
|
||||
* @param height The height in pixels */
|
||||
public void drawRectangle (int x, int y, int width, int height) {
|
||||
rectangle(x, y, width, height, DrawType.STROKE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an area form another Pixmap to this Pixmap.
|
||||
/** Draws an area form another Pixmap to this Pixmap.
|
||||
*
|
||||
* @param pixmap The other Pixmap
|
||||
* @param x The target x-coordinate (top left corner)
|
||||
* @param y The target y-coordinate (top left corner)
|
||||
*/
|
||||
public void drawPixmap(Pixmap pixmap, int x, int y) {
|
||||
context.drawImage(pixmap.getCanvasElement(), x, y);
|
||||
* @param x The target x-coordinate (top left corner)
|
||||
* @param y The target y-coordinate (top left corner) */
|
||||
public void drawPixmap (Pixmap pixmap, int x, int y) {
|
||||
CanvasElement image = pixmap.getCanvasElement();
|
||||
image(image, 0, 0, image.getWidth(), image.getHeight(), x, y, image.getWidth(), image.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an area form another Pixmap to this Pixmap.
|
||||
/** Draws an area form another Pixmap to this Pixmap.
|
||||
*
|
||||
* @param pixmap The other Pixmap
|
||||
* @param x The target x-coordinate (top left corner)
|
||||
* @param y The target y-coordinate (top left corner)
|
||||
* @param srcx The source x-coordinate (top left corner)
|
||||
* @param srcy The source y-coordinate (top left corner);
|
||||
* @param srcWidth The width of the area form the other Pixmap in pixels
|
||||
* @param srcHeight The height of the area form the other Pixmap in pixles
|
||||
*/
|
||||
public void drawPixmap(Pixmap pixmap, int x, int y, int srcx, int srcy, int srcWidth, int srcHeight) {
|
||||
context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, x, y, srcWidth, srcHeight);
|
||||
* @param pixmap The other Pixmap
|
||||
* @param x The target x-coordinate (top left corner)
|
||||
* @param y The target y-coordinate (top left corner)
|
||||
* @param srcx The source x-coordinate (top left corner)
|
||||
* @param srcy The source y-coordinate (top left corner);
|
||||
* @param srcWidth The width of the area form the other Pixmap in pixels
|
||||
* @param srcHeight The height of the area form the other Pixmap in pixles */
|
||||
public void drawPixmap (Pixmap pixmap, int x, int y, int srcx, int srcy, int srcWidth, int srcHeight) {
|
||||
CanvasElement image = pixmap.getCanvasElement();
|
||||
image(image, srcx, srcy, srcWidth, srcHeight, x, y, srcWidth, srcHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an area form another Pixmap to this Pixmap. This will automatically scale and stretch the source image to the
|
||||
/** Draws an area form another Pixmap to this Pixmap. This will automatically scale and stretch the source image to the
|
||||
* specified target rectangle. Use {@link Pixmap#setFilter(Filter)} to specify the type of filtering to be used (nearest
|
||||
* neighbour or bilinear).
|
||||
*
|
||||
* @param pixmap The other Pixmap
|
||||
* @param srcx The source x-coordinate (top left corner)
|
||||
* @param srcy The source y-coordinate (top left corner);
|
||||
* @param srcWidth The width of the area form the other Pixmap in pixels
|
||||
* @param pixmap The other Pixmap
|
||||
* @param srcx The source x-coordinate (top left corner)
|
||||
* @param srcy The source y-coordinate (top left corner);
|
||||
* @param srcWidth The width of the area form the other Pixmap in pixels
|
||||
* @param srcHeight The height of the area form the other Pixmap in pixles
|
||||
* @param dstx The target x-coordinate (top left corner)
|
||||
* @param dsty The target y-coordinate (top left corner)
|
||||
* @param dstWidth The target width
|
||||
* @param dstHeight the target height
|
||||
*/
|
||||
public void drawPixmap(Pixmap pixmap, int srcx, int srcy, int srcWidth, int srcHeight, int dstx, int dsty, int dstWidth,
|
||||
int dstHeight) {
|
||||
context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, dstx, dsty, dstWidth, dstHeight);
|
||||
* @param dstx The target x-coordinate (top left corner)
|
||||
* @param dsty The target y-coordinate (top left corner)
|
||||
* @param dstWidth The target width
|
||||
* @param dstHeight the target height */
|
||||
public void drawPixmap (Pixmap pixmap, int srcx, int srcy, int srcWidth, int srcHeight, int dstx, int dsty, int dstWidth,
|
||||
int dstHeight) {
|
||||
image(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, dstx, dsty, dstWidth, dstHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a rectangle starting at x, y extending by width to the right and by height downwards (y-axis points downwards) using
|
||||
/** Fills a rectangle starting at x, y extending by width to the right and by height downwards (y-axis points downwards) using
|
||||
* the current color.
|
||||
*
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param width The width in pixels
|
||||
* @param height The height in pixels
|
||||
*/
|
||||
public void fillRectangle(int x, int y, int width, int height) {
|
||||
context.fillRect(x, y, width, height);
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param width The width in pixels
|
||||
* @param height The height in pixels */
|
||||
public void fillRectangle (int x, int y, int width, int height) {
|
||||
rectangle(x, y, width, height, DrawType.FILL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a circle outline with the center at x,y and a radius using the current color and stroke width.
|
||||
/** Draws a circle outline with the center at x,y and a radius using the current color and stroke width.
|
||||
*
|
||||
* @param x The x-coordinate of the center
|
||||
* @param y The y-coordinate of the center
|
||||
* @param radius The radius in pixels
|
||||
*/
|
||||
public void drawCircle(int x, int y, int radius) {
|
||||
context.beginPath();
|
||||
context.arc(x, y, radius, 0, 2 * Math.PI, false);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
* @param x The x-coordinate of the center
|
||||
* @param y The y-coordinate of the center
|
||||
* @param radius The radius in pixels */
|
||||
public void drawCircle (int x, int y, int radius) {
|
||||
circle(x, y, radius, DrawType.STROKE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a circle with the center at x,y and a radius using the current color.
|
||||
/** Fills a circle with the center at x,y and a radius using the current color.
|
||||
*
|
||||
* @param x The x-coordinate of the center
|
||||
* @param y The y-coordinate of the center
|
||||
* @param radius The radius in pixels
|
||||
*/
|
||||
public void fillCircle(int x, int y, int radius) {
|
||||
context.beginPath();
|
||||
context.arc(x, y, radius, 0, 2 * Math.PI, false);
|
||||
context.fill();
|
||||
context.closePath();
|
||||
* @param x The x-coordinate of the center
|
||||
* @param y The y-coordinate of the center
|
||||
* @param radius The radius in pixels */
|
||||
public void fillCircle (int x, int y, int radius) {
|
||||
circle(x, y, radius, DrawType.FILL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a triangle with vertices at x1,y1 and x2,y2 and x3,y3 using the current color.
|
||||
/** Fills a triangle with vertices at x1,y1 and x2,y2 and x3,y3 using the current color.
|
||||
*
|
||||
* @param x1 The x-coordinate of vertex 1
|
||||
* @param y1 The y-coordinate of vertex 1
|
||||
* @param x2 The x-coordinate of vertex 2
|
||||
* @param y2 The y-coordinate of vertex 2
|
||||
* @param x3 The x-coordinate of vertex 3
|
||||
* @param y3 The y-coordinate of vertex 3
|
||||
*/
|
||||
public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
context.beginPath();
|
||||
context.moveTo(x1, y1);
|
||||
context.lineTo(x2, y2);
|
||||
context.lineTo(x3, y3);
|
||||
context.lineTo(x1, y1);
|
||||
context.fill();
|
||||
context.closePath();
|
||||
* @param y3 The y-coordinate of vertex 3 */
|
||||
public void fillTriangle (int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
triangle(x1, y1, x2, y2, x3, y3, DrawType.FILL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 32-bit RGBA8888 value of the pixel at x, y. For Alpha formats the RGB components will be one.
|
||||
/** Returns the 32-bit RGBA8888 value of the pixel at x, y. For Alpha formats the RGB components will be one.
|
||||
*
|
||||
* @param x The x-coordinate
|
||||
* @param y The y-coordinate
|
||||
* @return The pixel color in RGBA8888 format.
|
||||
*/
|
||||
public int getPixel(int x, int y) {
|
||||
* @return The pixel color in RGBA8888 format. */
|
||||
public int getPixel (int x, int y) {
|
||||
ensureCanvasExists();
|
||||
if (pixels == null) pixels = context.getImageData(0, 0, width, height).getData();
|
||||
int i = x * 4 + y * width * 4;
|
||||
int r = pixels.get(i + 0) & 0xff;
|
||||
@@ -402,26 +388,148 @@ public class Pixmap implements Disposable {
|
||||
return (r << 24) | (g << 16) | (b << 8) | (a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a pixel at the given location with the current color.
|
||||
/** Draws a pixel at the given location with the current color.
|
||||
*
|
||||
* @param x the x-coordinate
|
||||
* @param y the y-coordinate */
|
||||
public void drawPixel (int x, int y) {
|
||||
rectangle(x, y, 1, 1, DrawType.FILL);
|
||||
}
|
||||
|
||||
/** Draws a pixel at the given location with the given color.
|
||||
*
|
||||
* @param x the x-coordinate
|
||||
* @param y the y-coordinate
|
||||
*/
|
||||
public void drawPixel(int x, int y) {
|
||||
context.fillRect(x, y, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a pixel at the given location with the given color.
|
||||
*
|
||||
* @param x the x-coordinate
|
||||
* @param y the y-coordinate
|
||||
* @param color the color in RGBA8888 format.
|
||||
*/
|
||||
public void drawPixel(int x, int y, int color) {
|
||||
* @param color the color in RGBA8888 format. */
|
||||
public void drawPixel (int x, int y, int color) {
|
||||
setColor(color);
|
||||
drawPixel(x, y);
|
||||
}
|
||||
|
||||
private void circle (int x, int y, int radius, DrawType drawType) {
|
||||
ensureCanvasExists();
|
||||
if (blending == Blending.None) {
|
||||
context.setFillStyle(clearColor);
|
||||
context.setStrokeStyle(clearColor);
|
||||
context.setGlobalCompositeOperation("destination-out");
|
||||
context.beginPath();
|
||||
context.arc(x, y, radius, 0, 2 * Math.PI, false);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
context.setFillStyle(color);
|
||||
context.setStrokeStyle(color);
|
||||
context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
|
||||
}
|
||||
context.beginPath();
|
||||
context.arc(x, y, radius, 0, 2 * Math.PI, false);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
pixels = null;
|
||||
}
|
||||
|
||||
private void line(int x, int y, int x2, int y2, DrawType drawType) {
|
||||
ensureCanvasExists();
|
||||
if (blending == Blending.None) {
|
||||
context.setFillStyle(clearColor);
|
||||
context.setStrokeStyle(clearColor);
|
||||
context.setGlobalCompositeOperation("destination-out");
|
||||
context.beginPath();
|
||||
context.moveTo(x, y);
|
||||
context.lineTo(x2, y2);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
context.setFillStyle(color);
|
||||
context.setStrokeStyle(color);
|
||||
context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
|
||||
}
|
||||
context.beginPath();
|
||||
context.moveTo(x, y);
|
||||
context.lineTo(x2, y2);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
pixels = null;
|
||||
}
|
||||
|
||||
private void rectangle(int x, int y, int width, int height, DrawType drawType) {
|
||||
ensureCanvasExists();
|
||||
if (blending == Blending.None) {
|
||||
context.setFillStyle(clearColor);
|
||||
context.setStrokeStyle(clearColor);
|
||||
context.setGlobalCompositeOperation("destination-out");
|
||||
context.beginPath();
|
||||
context.rect(x, y, width, height);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
context.setFillStyle(color);
|
||||
context.setStrokeStyle(color);
|
||||
context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
|
||||
}
|
||||
context.beginPath();
|
||||
context.rect(x, y, width, height);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
pixels = null;
|
||||
}
|
||||
|
||||
private void triangle(int x1, int y1, int x2, int y2, int x3, int y3, DrawType drawType) {
|
||||
ensureCanvasExists();
|
||||
if (blending == Blending.None) {
|
||||
context.setFillStyle(clearColor);
|
||||
context.setStrokeStyle(clearColor);
|
||||
context.setGlobalCompositeOperation("destination-out");
|
||||
context.beginPath();
|
||||
context.moveTo(x1,y1);
|
||||
context.lineTo(x2,y2);
|
||||
context.lineTo(x3,y3);
|
||||
context.lineTo(x1,y1);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
context.setFillStyle(color);
|
||||
context.setStrokeStyle(color);
|
||||
context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
|
||||
}
|
||||
context.beginPath();
|
||||
context.moveTo(x1,y1);
|
||||
context.lineTo(x2,y2);
|
||||
context.lineTo(x3,y3);
|
||||
context.lineTo(x1,y1);
|
||||
fillOrStrokePath(drawType);
|
||||
context.closePath();
|
||||
pixels = null;
|
||||
}
|
||||
|
||||
private void image (CanvasElement image, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight) {
|
||||
ensureCanvasExists();
|
||||
if (blending == Blending.None) {
|
||||
context.setFillStyle(clearColor);
|
||||
context.setStrokeStyle(clearColor);
|
||||
context.setGlobalCompositeOperation("destination-out");
|
||||
context.beginPath();
|
||||
context.rect(dstX, dstY, dstWidth, dstHeight);
|
||||
fillOrStrokePath(DrawType.FILL);
|
||||
context.closePath();
|
||||
context.setFillStyle(color);
|
||||
context.setStrokeStyle(color);
|
||||
context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
|
||||
}
|
||||
context.drawImage(image, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight);
|
||||
pixels = null;
|
||||
}
|
||||
|
||||
private void fillOrStrokePath(DrawType drawType) {
|
||||
ensureCanvasExists();
|
||||
switch (drawType) {
|
||||
case FILL:
|
||||
context.fill();
|
||||
break;
|
||||
case STROKE:
|
||||
context.stroke();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private enum DrawType {
|
||||
FILL, STROKE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
22
vtm-web/src/org/oscim/gdx/emu/java/io/FileInputStream.java
Normal file
22
vtm-web/src/org/oscim/gdx/emu/java/io/FileInputStream.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package java.io;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class FileInputStream extends InputStream {
|
||||
|
||||
static final Logger log = LoggerFactory.getLogger(FileInputStream.class);
|
||||
|
||||
public FileInputStream(File f) {
|
||||
|
||||
}
|
||||
|
||||
public FileInputStream(String s) throws FileNotFoundException {
|
||||
log.debug("FileInputStream {}", s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user