Added project files
This commit is contained in:
commit
c4106a0ce5
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build/
|
73
build.xml
Normal file
73
build.xml
Normal file
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="slgui" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project slgui.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="slgui-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
3
manifest.mf
Normal file
3
manifest.mf
Normal file
@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
1771
nbproject/build-impl.xml
Normal file
1771
nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
nbproject/genfiles.properties
Normal file
8
nbproject/genfiles.properties
Normal file
@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=46d6c371
|
||||
build.xml.script.CRC32=b385f2e2
|
||||
build.xml.stylesheet.CRC32=f85dc8f2@1.112.0.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=46d6c371
|
||||
nbproject/build-impl.xml.script.CRC32=9f3656df
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.112.0.48
|
95
nbproject/project.properties
Normal file
95
nbproject/project.properties
Normal file
@ -0,0 +1,95 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processor.options=
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.modulepath=\
|
||||
${run.modulepath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
debug.test.modulepath=\
|
||||
${run.test.modulepath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/slgui.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
dist.jlink.dir=${dist.dir}/jlink
|
||||
dist.jlink.output=${dist.jlink.dir}/slgui
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.external.vm=true
|
||||
javac.modulepath=
|
||||
javac.processormodulepath=
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=21
|
||||
javac.target=21
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.modulepath=\
|
||||
${javac.modulepath}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.html5=false
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
# The jlink additional root modules to resolve
|
||||
jlink.additionalmodules=
|
||||
# The jlink additional command line parameters
|
||||
jlink.additionalparam=
|
||||
jlink.launcher=true
|
||||
jlink.launcher.name=slgui
|
||||
main.class=slgui.demo.Main
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.modulepath=\
|
||||
${javac.modulepath}
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
run.test.modulepath=\
|
||||
${javac.test.modulepath}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
15
nbproject/project.xml
Normal file
15
nbproject/project.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>slgui</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
20
src/slgui/base/MediaApp.java
Normal file
20
src/slgui/base/MediaApp.java
Normal file
@ -0,0 +1,20 @@
|
||||
package slgui.base;
|
||||
|
||||
/** This should be subclassed by applications which use the media API.
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public abstract class MediaApp {
|
||||
protected final MediaAppId appId;
|
||||
protected final MediaAppDelegate appDelegate;
|
||||
|
||||
public MediaApp(MediaSystemDelegate systemDelegate, MediaAppId appId) {
|
||||
this.appId = appId;
|
||||
appDelegate = systemDelegate.pairApp(this);
|
||||
}
|
||||
|
||||
public MediaAppId getId() {
|
||||
return appId;
|
||||
}
|
||||
}
|
10
src/slgui/base/MediaAppDelegate.java
Normal file
10
src/slgui/base/MediaAppDelegate.java
Normal file
@ -0,0 +1,10 @@
|
||||
package slgui.base;
|
||||
|
||||
/** Represents an object which can be used by an application to interact with the world.
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public interface MediaAppDelegate {
|
||||
public MediaSystemDelegate getSystemDelegate();
|
||||
}
|
44
src/slgui/base/MediaAppId.java
Normal file
44
src/slgui/base/MediaAppId.java
Normal file
@ -0,0 +1,44 @@
|
||||
package slgui.base;
|
||||
|
||||
/** This should uniquely identify an installed/installable version of an application on the system,
|
||||
* but without any installation-specific details such as file paths. This can be used for checking versions,
|
||||
* loading default configurations, for generating default installation paths, (in the future) sending messages
|
||||
* between apps, and so on. For the most part though, it's just used internally wherever the app name is
|
||||
* needed. It also helps to ensure that app release ids are reasonably consistent
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public final class MediaAppId {
|
||||
public final String marketId;
|
||||
public final String developerId;
|
||||
public final String releaseId;
|
||||
public final int majorVersion;
|
||||
public final int minorVersion;
|
||||
public final String patchId;
|
||||
|
||||
public MediaAppId(String marketId, String developerId, String releaseId, int majorVersion, int minorVersion, String patchId) {
|
||||
this.marketId = checkString(marketId);
|
||||
this.developerId = checkString(developerId);
|
||||
this.releaseId = checkString(releaseId);
|
||||
this.majorVersion = majorVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
this.patchId = checkString(patchId);
|
||||
}
|
||||
|
||||
public boolean stringFails(String str) {
|
||||
if (str.length() < 1) {
|
||||
return true;
|
||||
} else {
|
||||
return str.contains("/") || str.contains("\\") || str.contains("-") || str.contains("*") || str.contains(".");
|
||||
}
|
||||
}
|
||||
|
||||
public String checkString(String str) {
|
||||
if (stringFails(str)) {
|
||||
throw new Error("The string '" + str + "' contains characters forbidden in app ids");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
23
src/slgui/base/MediaBox.java
Normal file
23
src/slgui/base/MediaBox.java
Normal file
@ -0,0 +1,23 @@
|
||||
package slgui.base;
|
||||
|
||||
public final class MediaBox {
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final double width;
|
||||
public final double height;
|
||||
|
||||
public MediaBox(double x, double y, double width, double height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public boolean hits(double x, double y) {
|
||||
return (x >= this.x) && (y >= this.y) && (x <= this.x + this.width) && (y <= this.y + this.height);
|
||||
}
|
||||
|
||||
public boolean hits(MediaPoint p) {
|
||||
return hits(p.x, p.y);
|
||||
}
|
||||
}
|
356
src/slgui/base/MediaFont.java
Normal file
356
src/slgui/base/MediaFont.java
Normal file
@ -0,0 +1,356 @@
|
||||
package slgui.base;
|
||||
|
||||
/** A minimalist font system which can be used directly on top of a MediaPainter
|
||||
* (or subclass).
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public class MediaFont {
|
||||
public /*final*/ double scale;
|
||||
public /*final*/ double rscale;
|
||||
|
||||
public MediaFont(double scale) {
|
||||
this.scale = scale;
|
||||
this.rscale = scale/2;
|
||||
}
|
||||
|
||||
public double glyphWidth(int value) {
|
||||
switch (value) {
|
||||
default:
|
||||
return 8*scale;
|
||||
}
|
||||
}
|
||||
|
||||
public double glyphXAdvance(int value) {
|
||||
return glyphWidth(value);
|
||||
}
|
||||
|
||||
public void renderGlyph(MediaPainter p, int value, double x, double y, int pixel) {
|
||||
if (value >= 'A' && value <= 'Z') {
|
||||
renderAZ(p, value, x, y, pixel);
|
||||
} else if (value >= 'a' && value <= 'z') {
|
||||
renderaz(p, value, x, y, pixel);
|
||||
} else if (value >= '0' && value <= '9') {
|
||||
render09(p, value, x, y, pixel);
|
||||
} else if (value == ' ' || value == '\t' || value == '\n') {
|
||||
// Empty
|
||||
} else if (isPunct(value)) {
|
||||
renderPunct(p, value, x, y, pixel);
|
||||
} else {
|
||||
renderTofu(p, value, x, y, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPunct(int value) {
|
||||
switch (value) {
|
||||
case '.':
|
||||
case '!':
|
||||
case '?':
|
||||
case ',':
|
||||
case ':':
|
||||
case '\'':
|
||||
case '\"':
|
||||
case '/':
|
||||
case '\\':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void render(MediaPainter p, String value, double x, double y, int pixel) {
|
||||
int[] codepoints = value.codePoints().toArray();
|
||||
for (int i = 0; i < codepoints.length; i++) {
|
||||
int c = codepoints[i];
|
||||
renderGlyph(p, c, x, y, pixel);
|
||||
x += glyphXAdvance(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderTofu(MediaPainter p, int value, double x, double y, int pixel) {
|
||||
p.line(x, y, x + 7*scale, y, pixel, 1*rscale);
|
||||
p.line(x, y + 7*scale, x + 7*scale, y + 7*scale, pixel, 1*rscale);
|
||||
p.line(x, y, x, y + 7*scale, pixel, 1*rscale);
|
||||
p.line(x + 7*scale, y, x + 7*scale, y + 7*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 6*scale, y + 1*scale, 0xFFFF0000, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, 0xFFFF0000, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 1*scale, y + 6*scale, 0xFFFF0000, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, 0xFFFF0000, 1*rscale);
|
||||
}
|
||||
|
||||
public void renderPunct(MediaPainter p, int value, double x, double y, int pixel) {
|
||||
switch(value) {
|
||||
case '!':
|
||||
p.line(x+3.5*scale, y + 1*scale, x + 3.5*scale, y + 4*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 6*scale, x + 3.5*scale, y + 6*scale, pixel, 1.5*rscale);
|
||||
break;
|
||||
case '?':
|
||||
p.line(x+3.5*scale, y + 1*scale, x + 5*scale, y + 2.5*scale, pixel, 1*rscale);
|
||||
p.line(x+5*scale, y + 2.5*scale, x + 3.5*scale, y + 4*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 6*scale, x + 3.5*scale, y + 6*scale, pixel, 1.5*rscale);
|
||||
break;
|
||||
case '.':
|
||||
p.line(x+3.5*scale, y + 6*scale, x + 3.5*scale, y + 6*scale, pixel, 1.5*rscale);
|
||||
break;
|
||||
case ':':
|
||||
p.line(x+3.5*scale, y + 3.5*scale, x + 3.5*scale, y + 3.5*scale, pixel, 1.5*rscale);
|
||||
p.line(x+3.5*scale, y + 6*scale, x + 3.5*scale, y + 6*scale, pixel, 1.5*rscale);
|
||||
break;
|
||||
case ',':
|
||||
p.line(x+3*scale, y + 6*scale, x + 4*scale, y + 5*scale, pixel, 1.5*rscale);
|
||||
break;
|
||||
case '/':
|
||||
p.line(x+1*scale, y+6*scale, x+6*scale, y+1*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '\\':
|
||||
p.line(x+6*scale, y+6*scale, x+1*scale, y+1*scale, pixel, 1*rscale);
|
||||
break;
|
||||
default:
|
||||
renderTofu(p, value, x, y, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void render09(MediaPainter p, int value, double x, double y, int pixel) {
|
||||
switch(value) {
|
||||
case '0':
|
||||
p.line(x + 1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '1':
|
||||
p.line(x+3.5*scale, y + 1*scale, x + 3.5*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 1*scale, x + 2.25*scale, y + 1.75*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '2':
|
||||
p.line(x + 2*scale, y + 1*scale, x + 5*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 2.25*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x + 2*scale, y + 1*scale, x + 1*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x + 5*scale, y + 1*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 3.5*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '3':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '4':
|
||||
p.line(x+1*scale, y + 4.25*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 4.25*scale, x + 6*scale, y + 4.25*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '5':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 2.25*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 2.25*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '6':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 1*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '7':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 1*scale, x + 3.5*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '8':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 1*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 1*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case '9':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
//p.line(x+1*scale, y + 6*scale, x + 1*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 1*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
default:
|
||||
renderTofu(p, value, x, y, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderAZ(MediaPainter p, int value, double x, double y, int pixel) {
|
||||
switch(value) {
|
||||
case 'A':
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y+1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 3.5*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'B':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 4.75*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 4.75*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'C':
|
||||
//p.line(x+6*scale, y + 1*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
//p.line(x+6*scale, y + 6*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
|
||||
p.line(x + 1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'D':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'E':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'F':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'G':
|
||||
p.line(x + 1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 3.5*scale, x + 3.5*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'H':
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y+1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'I':
|
||||
p.line(x+3.5*scale, y + 1*scale, x + 3.5*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'J':
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 3.5*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'K':
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 1*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 6*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'L':
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'M':
|
||||
p.line(x+1*scale, y + 1*scale, x + 3.5*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 3.5*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y+1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'N':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y+1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'O':
|
||||
p.line(x + 1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'P':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
//p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'Q':
|
||||
p.line(x + 1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 3.5*scale, x + 7*scale, y + 7*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'R':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 2.25*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'S':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 3.5*scale, x + 6*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 1*scale, x + 1*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+6*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'T':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 1*scale, x + 3.5*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'U':
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'V':
|
||||
p.line(x + 1*scale, y + 1*scale, x + 3.5*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 3.5*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'W':
|
||||
p.line(x+1*scale, y + 6*scale, x + 3.5*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 3.5*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y+1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'X':
|
||||
p.line(x+1*scale, y + 1*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x+1*scale, y + 6*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'Y':
|
||||
p.line(x+1*scale, y + 1*scale, x + 3.5*scale, y + 3.5*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y + 3.5*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x+3.5*scale, y+3.5*scale, x + 3.5*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
case 'Z':
|
||||
p.line(x + 1*scale, y + 1*scale, x + 6*scale, y + 1*scale, pixel, 1*rscale);
|
||||
p.line(x + 1*scale, y + 6*scale, x + 6*scale, y + 6*scale, pixel, 1*rscale);
|
||||
p.line(x + 6*scale, y + 1*scale, x + 1*scale, y + 6*scale, pixel, 1*rscale);
|
||||
break;
|
||||
default:
|
||||
renderTofu(p, value, x, y, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderaz(MediaPainter p, int value, double x, double y, int pixel) {
|
||||
double oldscale = scale;
|
||||
double oldrscale = rscale;
|
||||
switch(value) {
|
||||
default:
|
||||
try {
|
||||
x += 1*scale;
|
||||
y += 1*scale;
|
||||
scale *= 0.8;
|
||||
rscale *= 0.8;
|
||||
//p.line(x, y, x + 7*scale, y, 0xFFFF0000, 1*scale);
|
||||
renderAZ(p, ((int)'A') + (value - ((int) 'a')), x, y, pixel);
|
||||
} finally {
|
||||
scale = oldscale;
|
||||
rscale = oldrscale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
86
src/slgui/base/MediaInputState.java
Normal file
86
src/slgui/base/MediaInputState.java
Normal file
@ -0,0 +1,86 @@
|
||||
package slgui.base;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MediaInputState {
|
||||
private HashMap<String, MediaPointerState> pointerstates = new HashMap<String, MediaPointerState>();
|
||||
private HashMap<String, Boolean> keystates = new HashMap<String, Boolean>();
|
||||
double lastX, lastY;
|
||||
|
||||
public MediaInputState() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public synchronized void resetKeypad() {
|
||||
keystates = new HashMap<String, Boolean>();
|
||||
}
|
||||
|
||||
public synchronized void resetPointers() {
|
||||
pointerstates = new HashMap<String, MediaPointerState>();
|
||||
}
|
||||
|
||||
public synchronized MediaPointerState setPointer(String id, double x, double y, int nbuttons, MediaPointerButton... buttons) {
|
||||
if (nbuttons < 0) {
|
||||
pointerstates.remove(id);
|
||||
return null;
|
||||
}
|
||||
if (!pointerstates.containsKey(id)) {
|
||||
pointerstates.put(id, new MediaPointerState());
|
||||
}
|
||||
MediaPointerState s = pointerstates.get(id);
|
||||
s.reset(id);
|
||||
s.setCoordinates(x, y);
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
s.setButtons(nbuttons, 0);
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
s.setButton(buttons[i], true);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean hoverWithin(double x, double y, double width, double height) {
|
||||
MediaPointerState[] p = currentPointers();
|
||||
for (int i = 0; i < p.length; i++) {
|
||||
if (p[i].hoverWithin(x,y,width,height)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean downWithin(MediaPointerButton b, double x, double y, double width, double height) {
|
||||
MediaPointerState[] p = currentPointers();
|
||||
for (int i = 0; i < p.length; i++) {
|
||||
if (p[i].hoverWithin(x,y,width,height) && p[i].buttonDown(b)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized MediaPointerState[] currentPointers() {
|
||||
return pointerstates.values().toArray(new MediaPointerState[0]);
|
||||
}
|
||||
|
||||
public synchronized void setKeypad(String value, boolean down) {
|
||||
keystates.put(value, down);
|
||||
}
|
||||
|
||||
public synchronized boolean keypadDown(String value) {
|
||||
if (keystates.containsKey(value)) {
|
||||
return keystates.get(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public double lastPointerX() {
|
||||
return lastX;
|
||||
}
|
||||
|
||||
public double lastPointerY() {
|
||||
return lastY;
|
||||
}
|
||||
|
||||
}
|
77
src/slgui/base/MediaModel.java
Normal file
77
src/slgui/base/MediaModel.java
Normal file
@ -0,0 +1,77 @@
|
||||
package slgui.base;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import slgui.themes.KeypadType;
|
||||
import slgui.themes.Theme;
|
||||
|
||||
public class MediaModel {
|
||||
private int width;
|
||||
private int height;
|
||||
MediaFont font = new MediaFont(2);
|
||||
private MediaInputState input = new MediaInputState();
|
||||
|
||||
public MediaModel() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public void assertScreenSize(int w, int h) {
|
||||
if (getWidth() != w || getHeight() != h) {
|
||||
width = w;
|
||||
height = h;
|
||||
screenSizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void setInputState(MediaInputState input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public MediaInputState getInputState() {
|
||||
return input;
|
||||
}
|
||||
|
||||
protected void screenSizeChanged() {
|
||||
//System.err.println("NOTE: Screen size changed to " + width + "x" + height);
|
||||
}
|
||||
|
||||
public void attachView(MediaViewDelegate v) {
|
||||
|
||||
}
|
||||
|
||||
public void detachView(MediaViewDelegate v) {
|
||||
|
||||
}
|
||||
|
||||
public void paintView(MediaViewDelegate v, MediaPainter p) {
|
||||
/*
|
||||
p.line(10, 100, getWidth()-10, getHeight()-100, 0xFFFF0000, 10.0);
|
||||
p.line(getWidth()-100, 10, 100, getHeight()-10, 0xFFFF0000, 1.0);
|
||||
font.render(p, "Hello, world!", 100, 200, 0xFF50C0FF);
|
||||
new MediaFont(1).render(p, "Hello, world!", 100, 225, 0xFF50C0FF);
|
||||
new MediaFont(4).render(p, "Hello, world! 0123456789", 100, 250, 0xFF50C0FF);
|
||||
new MediaFont(4).render(p, "Hello... world?", 100, 300, 0xFF50C0FF);
|
||||
new MediaFont(2).render(p, "Sphinx of black quartz, judge my vow.", 100, 350, 0xFF50C0FF);
|
||||
new MediaFont(1).render(p, "Sphinx of black quartz, judge my vow. 0123456789", 100, 400, 0xFF50C0FF);
|
||||
Theme t = new Theme();
|
||||
t.paintDemoWindow(p, "A window", 300, 25, 250, 150);
|
||||
t.paintDemoDesktop(p, "Demo", new Date().toLocaleString(), 0,0, getWidth(), getHeight(), KeypadType.LATIN_LOWER, Math.sin((System.currentTimeMillis()%3000)/1000.0));
|
||||
*/
|
||||
}
|
||||
|
||||
public boolean isKeyed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isAnimated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
}
|
21
src/slgui/base/MediaPainter.java
Normal file
21
src/slgui/base/MediaPainter.java
Normal file
@ -0,0 +1,21 @@
|
||||
package slgui.base;
|
||||
|
||||
/* A MediaPainter object represents a minimalist rendering target, i.e. something
|
||||
* which in theory could be implemented on (robotic) pen & paper, but which should
|
||||
* be equally convenient for on-screen use. The design focuses on pen-like operations
|
||||
* for this reason, and does not in itself provide a heap of convenience functions
|
||||
*/
|
||||
public abstract class MediaPainter {
|
||||
/** Returns the given x value, except "snapped" to the centre of the nearest pixel (if applicable). */
|
||||
public double snapX(double x) {
|
||||
return x;
|
||||
}
|
||||
/** Returns the given y value, except "snapped" to the centre of the nearest pixel (if applicable). */
|
||||
public double snapY(double y) {
|
||||
return y;
|
||||
}
|
||||
/** Draws a line with the given (ARGB32) pixel value and radius. */
|
||||
public abstract void line(double x1, double y1, double x2, double y2, int pixel, double radius);
|
||||
/** Fills a simple box with the given (ARGB32) pixel value. */
|
||||
public abstract void box(double x, double y, double width, double height, int pixel);
|
||||
}
|
11
src/slgui/base/MediaPoint.java
Normal file
11
src/slgui/base/MediaPoint.java
Normal file
@ -0,0 +1,11 @@
|
||||
package slgui.base;
|
||||
|
||||
public final class MediaPoint {
|
||||
public final double x;
|
||||
public final double y;
|
||||
|
||||
public MediaPoint(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
10
src/slgui/base/MediaPointerButton.java
Normal file
10
src/slgui/base/MediaPointerButton.java
Normal file
@ -0,0 +1,10 @@
|
||||
package slgui.base;
|
||||
|
||||
public enum MediaPointerButton {
|
||||
/** This would usually correspond to the left mouse button, or a regular touch event. */
|
||||
MAIN,
|
||||
/** This would usually correspond to the right mouse button (if present). */
|
||||
ALT,
|
||||
/** This would usually correspond to the middle mouse button, or scrollwheel being pressed (if either are present). */
|
||||
MIDDLE
|
||||
}
|
73
src/slgui/base/MediaPointerState.java
Normal file
73
src/slgui/base/MediaPointerState.java
Normal file
@ -0,0 +1,73 @@
|
||||
package slgui.base;
|
||||
|
||||
public class MediaPointerState {
|
||||
String pointerId;
|
||||
double x, y;
|
||||
int buttonFlags;
|
||||
int nbuttons;
|
||||
|
||||
public MediaPointerState() {
|
||||
reset(null);
|
||||
}
|
||||
|
||||
public synchronized void reset(String pointerId) {
|
||||
this.pointerId = pointerId;
|
||||
x = -1;
|
||||
y = -1;
|
||||
nbuttons = -1;
|
||||
buttonFlags = 0;
|
||||
}
|
||||
|
||||
public synchronized void setCoordinates(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public synchronized MediaPoint getCoordinates() {
|
||||
return new MediaPoint(x, y);
|
||||
}
|
||||
|
||||
public synchronized void setButtons(int numberOfButtons, int buttonFlags) {
|
||||
this.nbuttons = numberOfButtons;
|
||||
this.buttonFlags = buttonFlags;
|
||||
}
|
||||
|
||||
public synchronized boolean buttonDown(MediaPointerButton b) {
|
||||
return buttonExists(b) && ((buttonFlags & (1 << b.ordinal())) != 0);
|
||||
}
|
||||
|
||||
public synchronized void setButton(MediaPointerButton b, boolean down) {
|
||||
if (b != MediaPointerButton.MAIN && nbuttons < b.ordinal()+1) {
|
||||
nbuttons = b.ordinal()+1;
|
||||
}
|
||||
if (down) {
|
||||
buttonFlags |= (1 << b.ordinal());
|
||||
} else {
|
||||
buttonFlags &= ~(1 << b.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean isTouch() {
|
||||
return nbuttons == 0;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return pointerId != null;
|
||||
}
|
||||
|
||||
public synchronized boolean buttonExists(MediaPointerButton b) {
|
||||
if (b == MediaPointerButton.MAIN) {
|
||||
return true;
|
||||
} else {
|
||||
return nbuttons >= b.ordinal()+1;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hoverWithin(double x2, double y2, double width, double height) {
|
||||
if (x >= x2 && x <= x2 + width && y >= y2 && y <= y2 + height) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
10
src/slgui/base/MediaSystemDelegate.java
Normal file
10
src/slgui/base/MediaSystemDelegate.java
Normal file
@ -0,0 +1,10 @@
|
||||
package slgui.base;
|
||||
|
||||
/** Represents an object which can be used to launch applications.
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public interface MediaSystemDelegate {
|
||||
MediaAppDelegate pairApp(MediaApp app);
|
||||
}
|
6
src/slgui/base/MediaViewDelegate.java
Normal file
6
src/slgui/base/MediaViewDelegate.java
Normal file
@ -0,0 +1,6 @@
|
||||
package slgui.base;
|
||||
|
||||
/** This represents an "outer" view which holds a MediaModel. */
|
||||
public interface MediaViewDelegate {
|
||||
|
||||
}
|
35
src/slgui/demo/Main.java
Normal file
35
src/slgui/demo/Main.java
Normal file
@ -0,0 +1,35 @@
|
||||
package slgui.demo;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import slgui.base.MediaModel;
|
||||
import slgui.space.DemoSpaceDelegate;
|
||||
import slgui.space.SpaceMediaModel;
|
||||
import slgui.space.SpaceState;
|
||||
import slgui.swing.GameWindow;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DemoSpaceDelegate d = new DemoSpaceDelegate();
|
||||
SpaceState space = new SpaceState(d);
|
||||
SpaceMediaModel model = new SpaceMediaModel(space);
|
||||
|
||||
GameWindow w = new GameWindow("ZGame Demo");
|
||||
w.setSize(640, 480);
|
||||
w.setMinimumSize(new Dimension(400,400));
|
||||
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
//w.setModel(new MediaModel());
|
||||
w.setModel(model);
|
||||
w.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
86
src/slgui/gfx/Painter.java
Normal file
86
src/slgui/gfx/Painter.java
Normal file
@ -0,0 +1,86 @@
|
||||
package slgui.gfx;
|
||||
|
||||
import slgui.base.MediaPainter;
|
||||
|
||||
/** A Painter object holds a graphics state which can be used for immediate rendering operations.
|
||||
* Painter objects extend the minimalist MediaPainter class with an internal context stack and
|
||||
* additional, more-convenient rendering functions.
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*/
|
||||
public class Painter extends MediaPainter {
|
||||
private final MediaPainter target;
|
||||
private final PainterContext[] contexts;
|
||||
private int stackIndex = -1;
|
||||
|
||||
/* The following should have equivalents in the PainterContext class: */
|
||||
Transformer transformer = Transformer.DIRECT;
|
||||
|
||||
public Painter(MediaPainter target, int stackmax) {
|
||||
this.target = target;
|
||||
contexts = new PainterContext[stackmax];
|
||||
}
|
||||
|
||||
public PainterContext contextAt(int index) {
|
||||
if (contexts[index] == null) {
|
||||
contexts[index] = new PainterContext();
|
||||
}
|
||||
return contexts[index];
|
||||
}
|
||||
|
||||
public void save() {
|
||||
int nsi = stackIndex + 1;
|
||||
|
||||
PainterContext ctx = contextAt(nsi);
|
||||
ctx.save(this, nsi);
|
||||
|
||||
stackIndex = nsi;
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
PainterContext ctx = contextAt(stackIndex);
|
||||
ctx.restore(this);
|
||||
ctx.reset();
|
||||
stackIndex = stackIndex - 1;
|
||||
}
|
||||
|
||||
/** Applies the given transformer (over the top of any already-applied transformers). */
|
||||
public void transform(Transformer t) {
|
||||
transformer = t.over(transformer);
|
||||
}
|
||||
|
||||
/** Applies a TranslateTransformer with the given translation offset coordinates (over the top of any already-applied transformers). */
|
||||
public void translate(double tx, double ty) {
|
||||
transform(new TranslateTransformer(tx, ty));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double snapX(double x) {
|
||||
return transformer.unX(target.snapX(transformer.x(x)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double snapY(double y) {
|
||||
return transformer.unY(target.snapY(transformer.y(y)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void line(double x1, double y1, double x2, double y2, int pixel, double radius) {
|
||||
x1 = transformer.x(x1);
|
||||
y1 = transformer.y(y1);
|
||||
x2 = transformer.x(x2);
|
||||
y2 = transformer.y(y2);
|
||||
radius = transformer.radius(radius);
|
||||
target.line(x1, y1, x2, y2, pixel, radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void box(double x, double y, double width, double height, int pixel) {
|
||||
x = transformer.x(x);
|
||||
y = transformer.x(x);
|
||||
width = transformer.width(width);
|
||||
height = transformer.height(height);
|
||||
target.box(x, y, width, height, pixel);
|
||||
}
|
||||
|
||||
}
|
36
src/slgui/gfx/PainterContext.java
Normal file
36
src/slgui/gfx/PainterContext.java
Normal file
@ -0,0 +1,36 @@
|
||||
package slgui.gfx;
|
||||
|
||||
/** A PainterContext holds a saved, internal state of a painter.
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public class PainterContext {
|
||||
Painter painter;
|
||||
int stackIndex;
|
||||
|
||||
/* The following should have equivalents in the Painter class. */
|
||||
Transformer transformer;
|
||||
|
||||
public PainterContext() {
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
painter = null;
|
||||
stackIndex = -1;
|
||||
|
||||
transformer = null;
|
||||
}
|
||||
|
||||
public void save(Painter p, int stackIndex) {
|
||||
this.painter = p;
|
||||
this.stackIndex = stackIndex;
|
||||
|
||||
this.transformer = p.transformer;
|
||||
}
|
||||
|
||||
public void restore(Painter p) {
|
||||
p.transformer = this.transformer;
|
||||
}
|
||||
}
|
57
src/slgui/gfx/Transformer.java
Normal file
57
src/slgui/gfx/Transformer.java
Normal file
@ -0,0 +1,57 @@
|
||||
package slgui.gfx;
|
||||
|
||||
/** A transformer represents an operation which applies to the coordinate space
|
||||
* (i.e. moving the x/y coordinates around in some pattern).
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public class Transformer {
|
||||
/** This is the only non-subclass instance of Transformer which should be used, other than base classes. */
|
||||
public static Transformer DIRECT = new Transformer();
|
||||
|
||||
protected Transformer() {
|
||||
}
|
||||
|
||||
public double x(double x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double y(double y) {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double unX(double x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double unY(double y) {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double width(double w) {
|
||||
return w;
|
||||
}
|
||||
|
||||
public double height(double h) {
|
||||
return h;
|
||||
}
|
||||
|
||||
public double radius(double r) {
|
||||
return (width(r) + height(r)) / 2;
|
||||
}
|
||||
|
||||
public Transformer over(Transformer other) {
|
||||
if (other == DIRECT) {
|
||||
return this;
|
||||
} else if (this == DIRECT) {
|
||||
return other;
|
||||
} else {
|
||||
return combinedTransformer(other);
|
||||
}
|
||||
}
|
||||
|
||||
public Transformer combinedTransformer(Transformer other) {
|
||||
throw new Error("TODO!");
|
||||
}
|
||||
}
|
47
src/slgui/gfx/TranslateTransformer.java
Normal file
47
src/slgui/gfx/TranslateTransformer.java
Normal file
@ -0,0 +1,47 @@
|
||||
package slgui.gfx;
|
||||
|
||||
/** A TranslateTransformer only adds a "translation" offset to the x/y coordinates. It has
|
||||
* no effect on other (width/height-related) coordinates.
|
||||
*
|
||||
* @author Zak Fenton
|
||||
*
|
||||
*/
|
||||
public final class TranslateTransformer extends Transformer {
|
||||
public final double tx;
|
||||
public final double ty;
|
||||
|
||||
public TranslateTransformer(double tx, double ty) {
|
||||
this.tx = tx;
|
||||
this.ty = ty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double x(double x) {
|
||||
return tx + x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double y(double y) {
|
||||
return tx + y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double unX(double x) {
|
||||
return x - tx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double unY(double y) {
|
||||
return y - ty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transformer combinedTransformer(Transformer other) {
|
||||
if (other instanceof TranslateTransformer) {
|
||||
TranslateTransformer o = (TranslateTransformer) other;
|
||||
return new TranslateTransformer(this.tx + o.tx, this.ty + o.ty);
|
||||
} else {
|
||||
return super.combinedTransformer(other);
|
||||
}
|
||||
}
|
||||
}
|
44
src/slgui/space/DemoSpaceDelegate.java
Normal file
44
src/slgui/space/DemoSpaceDelegate.java
Normal file
@ -0,0 +1,44 @@
|
||||
package slgui.space;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class DemoSpaceDelegate implements SpaceDelegate {
|
||||
|
||||
public DemoSpaceDelegate() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatus1() {
|
||||
return "Demo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatus2() {
|
||||
String t = new Date().toLocaleString();
|
||||
t = t.substring(t.indexOf(' '));
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMilliseconds() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachSpace(SpaceState space) {
|
||||
WindowState w = space.newWindow(new WindowDelegate() {
|
||||
});
|
||||
w.setCoordinates(100, 500, 320, 240);
|
||||
w.setTitle("Hello");
|
||||
w = space.newWindow(new WindowDelegate() {
|
||||
});
|
||||
w.setCoordinates(600, 500, 320, 240);
|
||||
w.setTitle("World");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachSpace(SpaceState state) {
|
||||
// No action by default.
|
||||
}
|
||||
}
|
8
src/slgui/space/SizingState.java
Normal file
8
src/slgui/space/SizingState.java
Normal file
@ -0,0 +1,8 @@
|
||||
package slgui.space;
|
||||
|
||||
public enum SizingState {
|
||||
MINIMISED,
|
||||
WINDOWED,
|
||||
MAXIMISED,
|
||||
FULLSCREEN
|
||||
}
|
10
src/slgui/space/SpaceDelegate.java
Normal file
10
src/slgui/space/SpaceDelegate.java
Normal file
@ -0,0 +1,10 @@
|
||||
package slgui.space;
|
||||
|
||||
public interface SpaceDelegate {
|
||||
public String getStatus1();
|
||||
public String getStatus2();
|
||||
public long getMilliseconds();
|
||||
|
||||
public void attachSpace(SpaceState state);
|
||||
public void detachSpace(SpaceState state);
|
||||
}
|
30
src/slgui/space/SpaceMediaModel.java
Normal file
30
src/slgui/space/SpaceMediaModel.java
Normal file
@ -0,0 +1,30 @@
|
||||
package slgui.space;
|
||||
|
||||
import slgui.base.MediaInputState;
|
||||
import slgui.base.MediaModel;
|
||||
import slgui.base.MediaPainter;
|
||||
import slgui.base.MediaViewDelegate;
|
||||
|
||||
public class SpaceMediaModel extends MediaModel {
|
||||
SpaceState space;
|
||||
|
||||
public SpaceMediaModel(SpaceState space) {
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void screenSizeChanged() {
|
||||
space.setCoordinates(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintView(MediaViewDelegate v, MediaPainter p) {
|
||||
space.paint(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputState(MediaInputState input) {
|
||||
super.setInputState(input);
|
||||
space.setInputState(input);
|
||||
}
|
||||
}
|
166
src/slgui/space/SpaceState.java
Normal file
166
src/slgui/space/SpaceState.java
Normal file
@ -0,0 +1,166 @@
|
||||
package slgui.space;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
import slgui.base.MediaBox;
|
||||
import slgui.base.MediaFont;
|
||||
import slgui.base.MediaInputState;
|
||||
import slgui.base.MediaPainter;
|
||||
import slgui.base.MediaPointerButton;
|
||||
import slgui.themes.KeypadType;
|
||||
import slgui.themes.PanelMode;
|
||||
import slgui.themes.StatusMode;
|
||||
import slgui.themes.Theme;
|
||||
|
||||
public class SpaceState {
|
||||
private SpaceDelegate delegate;
|
||||
private boolean dirty = true;
|
||||
private ArrayList<WindowState> windows = new ArrayList<WindowState>();
|
||||
WindowState dragging;
|
||||
double dragX, dragY;
|
||||
KeypadType keypad;
|
||||
KeypadType nextKeypad; /* This value is eventually assigned to "keypad", after animation. */
|
||||
MediaFont font = new MediaFont(2);
|
||||
|
||||
private double x, y, width, height;
|
||||
private MediaInputState input = new MediaInputState();
|
||||
|
||||
public SpaceState(SpaceDelegate delegate) {
|
||||
this.delegate = delegate;
|
||||
delegate.attachSpace(this);
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return dirty;
|
||||
}
|
||||
|
||||
public void markDirty(boolean value) {
|
||||
this.dirty = value;
|
||||
}
|
||||
|
||||
public void markDirty() {
|
||||
markDirty(true);
|
||||
}
|
||||
|
||||
public void setInputState(MediaInputState input) {
|
||||
this.input = input;
|
||||
|
||||
if (input.downWithin(MediaPointerButton.MAIN, x, y, width, height)) {
|
||||
if (dragging != null) {
|
||||
if (dragX > 0) {
|
||||
System.out.println("Continguing drag");
|
||||
MediaBox coords = dragging.realCoordinates();
|
||||
dragging.setCoordinates(input.lastPointerX() - dragX, input.lastPointerY() - dragY, coords.width, coords.height);
|
||||
} else {
|
||||
System.out.println("Continguing resize");
|
||||
MediaBox coords = dragging.realCoordinates();
|
||||
dragging.setCoordinates(coords.x, coords.y, Math.max(100, input.lastPointerX() - coords.x), Math.max(100, input.lastPointerY() - coords.y));
|
||||
}
|
||||
} else {
|
||||
WindowState[] wins = currentWindows();
|
||||
for (int i = wins.length - 1; i >= 0; i--) {
|
||||
MediaBox coords = wins[i].realCoordinates();
|
||||
// TODO: The drag area should be dictated by the theme
|
||||
if (input.downWithin(MediaPointerButton.MAIN, coords.x, coords.y, coords.width, coords.height)) {
|
||||
if (input.downWithin(MediaPointerButton.MAIN, coords.x + 24, coords.y, coords.width-48, 24)) {
|
||||
System.out.println("Starting drag");
|
||||
dragging = wins[i];
|
||||
dragging.bringToFront();
|
||||
dragX = input.lastPointerX() - coords.x;
|
||||
dragY = input.lastPointerY() - coords.y;
|
||||
System.out.println("Dragx=" +dragX + "y=" + dragY);
|
||||
} else if (input.downWithin(MediaPointerButton.MAIN, coords.x + coords.width-16, coords.y + coords.height-16, 16, 16)) {
|
||||
System.out.println("Starting resize");
|
||||
dragging = wins[i];
|
||||
dragging.bringToFront();
|
||||
dragX = input.lastPointerX() - (coords.x + coords.width);
|
||||
dragY = input.lastPointerY() - (coords.y + coords.height);
|
||||
System.out.println("Dragx=" +dragX + "y=" + dragY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dragging = null;
|
||||
}
|
||||
}
|
||||
|
||||
public MediaInputState getInputState() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public synchronized WindowState newWindow(WindowDelegate delegate) {
|
||||
WindowState result = new WindowState(this, delegate);
|
||||
windows.add(result);
|
||||
markDirty();
|
||||
return result;
|
||||
}
|
||||
|
||||
public synchronized void bringToFront(WindowState w) {
|
||||
int winidx = windows.indexOf(w);
|
||||
if (winidx < 0) {
|
||||
return;
|
||||
}
|
||||
ArrayList<WindowState> newWindows = new ArrayList<WindowState>(windows.size());
|
||||
for (int i = 0; i < windows.size(); i++) {
|
||||
if (i < winidx) {
|
||||
newWindows.add(windows.get(i));
|
||||
} else if (i == windows.size()-1) {
|
||||
newWindows.add(w);
|
||||
} else {
|
||||
newWindows.add(windows.get(i + 1));
|
||||
}
|
||||
}
|
||||
windows = newWindows;
|
||||
}
|
||||
|
||||
public void setCoordinates(double x, double y, double width, double height) {
|
||||
if (x != this.x || y != this.y || width != this.width || height != this.height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized WindowState[] currentWindows() {
|
||||
return windows.toArray(new WindowState[0]);
|
||||
}
|
||||
|
||||
public void paint(MediaPainter p) {
|
||||
markDirty(false);
|
||||
p.line(10, 100, width-10, height-100, 0xFFFF0000, 10.0);
|
||||
p.line(width-100, 10, 100, height-10, 0xFFFF0000, 1.0);
|
||||
font.render(p, "Hello, world!", 100, 200, 0xFF50C0FF);
|
||||
new MediaFont(1).render(p, "Hello, world!", 100, 225, 0xFF50C0FF);
|
||||
new MediaFont(4).render(p, "Hello, world! 0123456789", 100, 250, 0xFF50C0FF);
|
||||
new MediaFont(4).render(p, "Hello... world?", 100, 300, 0xFF50C0FF);
|
||||
new MediaFont(2).render(p, "Sphinx of black quartz, judge my vow.", 100, 350, 0xFF50C0FF);
|
||||
new MediaFont(1).render(p, "Sphinx of black quartz, judge my vow. 0123456789", 100, 400, 0xFF50C0FF);
|
||||
|
||||
Theme t = new Theme();
|
||||
double keyanim = Math.sin((System.currentTimeMillis()%3000)/1000.0);
|
||||
MediaBox content = t.desktopContentArea(p, 0,0, width, height, KeypadType.LATIN_LOWER, keyanim, StatusMode.TOP, PanelMode.BOTTOM);
|
||||
|
||||
WindowState[] wins = currentWindows();
|
||||
double innerX = content.x;
|
||||
double innerY = content.y;
|
||||
double innerWidth = content.width;
|
||||
double innerHeight = content.height;
|
||||
for (int i = 0; i < wins.length; i++) {
|
||||
/* This will, if necessary, resize any windows to appropriate bounds. They may still
|
||||
* exceed these bounds (or be entirely "off-screen"), but only if the user has some
|
||||
* way of controlling the window.
|
||||
*/
|
||||
wins[i].realiseCoordinates(p, t, innerX, innerY, innerWidth, innerHeight);
|
||||
}
|
||||
for (int i = 0; i < wins.length; i++) {
|
||||
wins[i].paint(p, getInputState(), t);
|
||||
}
|
||||
t.paintDemoWindow(p, getInputState(), "A window", 300, 25, 250, 150);
|
||||
t.paintDemoDesktop(p, getInputState(), delegate.getStatus1(), delegate.getStatus2(), 0,0, width, height, KeypadType.LATIN_LOWER, keyanim, StatusMode.TOP, PanelMode.BOTTOM);
|
||||
}
|
||||
}
|
5
src/slgui/space/WindowDelegate.java
Normal file
5
src/slgui/space/WindowDelegate.java
Normal file
@ -0,0 +1,5 @@
|
||||
package slgui.space;
|
||||
|
||||
public interface WindowDelegate {
|
||||
|
||||
}
|
114
src/slgui/space/WindowState.java
Normal file
114
src/slgui/space/WindowState.java
Normal file
@ -0,0 +1,114 @@
|
||||
package slgui.space;
|
||||
|
||||
import slgui.base.MediaBox;
|
||||
import slgui.base.MediaInputState;
|
||||
import slgui.base.MediaPainter;
|
||||
import slgui.themes.Theme;
|
||||
|
||||
public class WindowState {
|
||||
private SpaceState space;
|
||||
private WindowDelegate delegate;
|
||||
private boolean dirty = true;
|
||||
private boolean redraw = true;
|
||||
private double realX, realY, realWidth, realHeight;
|
||||
private double configuredX, configuredY, configuredWidth, configuredHeight;
|
||||
private String title;
|
||||
private SizingState sizing = SizingState.WINDOWED;
|
||||
|
||||
WindowState(SpaceState space, WindowDelegate delegate) {
|
||||
this.space = space;
|
||||
this.delegate = delegate;
|
||||
title = "Untitled";
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return dirty;
|
||||
}
|
||||
|
||||
public void markDirty(boolean value) {
|
||||
if (value && !dirty) {
|
||||
space.markDirty();
|
||||
}
|
||||
this.dirty = value;
|
||||
}
|
||||
|
||||
public void markDirty() {
|
||||
markDirty(true);
|
||||
}
|
||||
|
||||
public boolean shouldRedraw() {
|
||||
return redraw;
|
||||
}
|
||||
|
||||
public void markRedraw(boolean value) {
|
||||
this.redraw = value;
|
||||
}
|
||||
|
||||
public void markRedraw() {
|
||||
markRedraw(true);
|
||||
}
|
||||
|
||||
public void setSizingState(SizingState sizing) {
|
||||
if (sizing != this.sizing) {
|
||||
this.sizing = sizing;
|
||||
markDirty();
|
||||
markRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
public SizingState getSizingState() {
|
||||
return this.sizing;
|
||||
}
|
||||
|
||||
public synchronized void realiseCoordinates(MediaPainter p, Theme t, double minX, double minY, double maxWidth, double maxHeight) {
|
||||
double newX = Math.max(minX, configuredX);
|
||||
double newY = Math.max(minY, configuredY);
|
||||
double newWidth = configuredWidth; //Math.min(maxWidth, configuredWidth);
|
||||
double newHeight = configuredHeight; //Math.min(maxHeight, configuredHeight);
|
||||
|
||||
if (newX > minX + maxWidth - 100) {
|
||||
newX = minX + maxWidth - 100;
|
||||
}
|
||||
if (newY > minY + maxHeight - 32) {
|
||||
newY = minY + maxHeight - 32;
|
||||
}
|
||||
|
||||
if (newX != realX || newY != realY || newWidth != realWidth || newHeight != realHeight) {
|
||||
realX = newX;
|
||||
realY = newY;
|
||||
realWidth = newWidth;
|
||||
realHeight = newHeight;
|
||||
markRedraw();
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setCoordinates(double x, double y, double width, double height) {
|
||||
if (x != configuredX || y != configuredY || width != configuredWidth || height != configuredHeight) {
|
||||
configuredX = x;
|
||||
configuredY = y;
|
||||
configuredWidth = width;
|
||||
configuredHeight = height;
|
||||
markRedraw();
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized MediaBox realCoordinates() {
|
||||
return new MediaBox(realX, realY, realWidth, realHeight);
|
||||
}
|
||||
|
||||
public void bringToFront() {
|
||||
space.bringToFront(this);
|
||||
}
|
||||
|
||||
public void paint(MediaPainter p, MediaInputState input, Theme t) {
|
||||
t.paintDemoWindow(p, input, title, realX, realY, realWidth, realHeight);
|
||||
|
||||
}
|
||||
|
||||
public void setTitle(String string) {
|
||||
this.title = string;
|
||||
markDirty();
|
||||
}
|
||||
}
|
5
src/slgui/space/WindowVisitor.java
Normal file
5
src/slgui/space/WindowVisitor.java
Normal file
@ -0,0 +1,5 @@
|
||||
package slgui.space;
|
||||
|
||||
public interface WindowVisitor {
|
||||
public void visitWindow(WindowState state);
|
||||
}
|
58
src/slgui/swing/G2DPainter.java
Normal file
58
src/slgui/swing/G2DPainter.java
Normal file
@ -0,0 +1,58 @@
|
||||
package slgui.swing;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import slgui.base.MediaPainter;
|
||||
|
||||
public class G2DPainter extends MediaPainter {
|
||||
public final Graphics2D g2d;
|
||||
int previousPixel;
|
||||
double previousRadius = -0.0;
|
||||
|
||||
public G2DPainter(Graphics2D g2d) {
|
||||
this.g2d = g2d;
|
||||
previousPixel = g2d.getColor().getRGB();
|
||||
setRadius(1.0);
|
||||
}
|
||||
|
||||
private final void setPixel(int x) {
|
||||
if (x != previousPixel) {
|
||||
Color c = new Color(x, true);
|
||||
g2d.setColor(c);
|
||||
previousPixel = x;
|
||||
}
|
||||
}
|
||||
|
||||
private final void setRadius(double x) {
|
||||
if (x != previousPixel) {
|
||||
BasicStroke stroke = new BasicStroke((float) x*2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
|
||||
g2d.setStroke(stroke);
|
||||
previousRadius = x;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void line(double x1, double y1, double x2, double y2, int pixel, double radius) {
|
||||
if (radius > 0) {
|
||||
x1 -= 0.5;
|
||||
y1 -= 0.5;
|
||||
x2 -= 0.5;
|
||||
y2 -= 0.5;
|
||||
setPixel(pixel);
|
||||
setRadius(radius);
|
||||
g2d.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void box(double x, double y, double width, double height, int pixel) {
|
||||
if (width > 0 && height > 0) {
|
||||
x -= 0.5;
|
||||
y -= 0.5;
|
||||
setPixel(pixel);
|
||||
g2d.fillRect((int) x, (int) y, (int) width, (int) height);
|
||||
}
|
||||
}
|
||||
}
|
165
src/slgui/swing/GameComponent.java
Normal file
165
src/slgui/swing/GameComponent.java
Normal file
@ -0,0 +1,165 @@
|
||||
package slgui.swing;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
|
||||
import javax.swing.Timer;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import slgui.base.MediaInputState;
|
||||
import slgui.base.MediaModel;
|
||||
import slgui.base.MediaPointerButton;
|
||||
import slgui.base.MediaViewDelegate;
|
||||
|
||||
public class GameComponent extends JComponent implements MediaViewDelegate {
|
||||
private MediaModel model;
|
||||
private Timer animationTimer;
|
||||
private MediaInputState input = new MediaInputState();
|
||||
|
||||
public GameComponent() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public synchronized void stopAnimationTimer() {
|
||||
if (animationTimer != null) {
|
||||
animationTimer.stop();
|
||||
animationTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void startAnimationTimer(int millis) {
|
||||
stopAnimationTimer();
|
||||
animationTimer = new Timer(millis, new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
animationTimer.setRepeats(true);
|
||||
animationTimer.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
g.setColor(Color.black);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
g.setColor(Color.red);
|
||||
if (model == null) {
|
||||
g.drawString("No game initialised", getWidth()/2, getHeight()/2);
|
||||
} else {
|
||||
model.assertScreenSize(getWidth(), getHeight());
|
||||
G2DPainter painter = new G2DPainter((Graphics2D) g);
|
||||
model.paintView(this, painter);
|
||||
g.drawString("TODO...", getWidth()/2, getHeight()/2);
|
||||
}
|
||||
//super.paintComponent(g);
|
||||
}
|
||||
|
||||
boolean leftDown = false;
|
||||
|
||||
public void setModel(MediaModel m) {
|
||||
if (m == model) {
|
||||
return;
|
||||
}
|
||||
if (model != null) {
|
||||
model.detachView(this);
|
||||
stopAnimationTimer();
|
||||
}
|
||||
model = m;
|
||||
if (model != null) {
|
||||
model.attachView(this);
|
||||
if (model.isAnimated()) {
|
||||
startAnimationTimer(100);
|
||||
}
|
||||
if (model.isKeyed()) {
|
||||
setFocusable(true);
|
||||
requestFocusInWindow();
|
||||
addKeyListener(new KeyListener() {
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
input.setKeypad(e.getKeyText(e.getKeyCode()), false);
|
||||
model.setInputState(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
input.setKeypad(e.getKeyText(e.getKeyCode()), true);
|
||||
model.setInputState(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addMouseListener(new MouseListener() {
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
leftDown = false;
|
||||
}
|
||||
input.setPointer("mouse", e.getX(), e.getY(), 1).setButton(MediaPointerButton.MAIN, leftDown);
|
||||
model.setInputState(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
leftDown = true;
|
||||
}
|
||||
input.setPointer("mouse", e.getX(), e.getY(), 1).setButton(MediaPointerButton.MAIN, leftDown);
|
||||
model.setInputState(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
addMouseMotionListener(new MouseMotionListener() {
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
input.setPointer("mouse", e.getX(), e.getY(), 1).setButton(MediaPointerButton.MAIN, leftDown);
|
||||
model.setInputState(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
input.setPointer("mouse", e.getX(), e.getY(), 1).setButton(MediaPointerButton.MAIN, leftDown);
|
||||
model.setInputState(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
41
src/slgui/swing/GameWindow.java
Normal file
41
src/slgui/swing/GameWindow.java
Normal file
@ -0,0 +1,41 @@
|
||||
package slgui.swing;
|
||||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.HeadlessException;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import slgui.base.MediaModel;
|
||||
|
||||
public class GameWindow extends JFrame {
|
||||
GameComponent gameComponent;
|
||||
|
||||
public GameWindow() throws HeadlessException {
|
||||
initUI();
|
||||
}
|
||||
|
||||
public GameWindow(GraphicsConfiguration gc) {
|
||||
super(gc);
|
||||
initUI();
|
||||
}
|
||||
|
||||
public GameWindow(String title) throws HeadlessException {
|
||||
super(title);
|
||||
initUI();
|
||||
}
|
||||
|
||||
public GameWindow(String title, GraphicsConfiguration gc) {
|
||||
super(title, gc);
|
||||
initUI();
|
||||
}
|
||||
|
||||
private void initUI() {
|
||||
gameComponent = new GameComponent();
|
||||
this.getContentPane().add(gameComponent);
|
||||
pack();
|
||||
}
|
||||
|
||||
public void setModel(MediaModel m) {
|
||||
gameComponent.setModel(m);
|
||||
}
|
||||
}
|
7
src/slgui/themes/ButtonState.java
Normal file
7
src/slgui/themes/ButtonState.java
Normal file
@ -0,0 +1,7 @@
|
||||
package slgui.themes;
|
||||
|
||||
public enum ButtonState {
|
||||
INACTIVE,
|
||||
ACTIVE,
|
||||
HOVER
|
||||
}
|
8
src/slgui/themes/KeypadType.java
Normal file
8
src/slgui/themes/KeypadType.java
Normal file
@ -0,0 +1,8 @@
|
||||
package slgui.themes;
|
||||
|
||||
public enum KeypadType {
|
||||
NONE,
|
||||
LATIN_LOWER,
|
||||
LATIN_UPPER,
|
||||
NUMBERS
|
||||
}
|
10
src/slgui/themes/PanelMode.java
Normal file
10
src/slgui/themes/PanelMode.java
Normal file
@ -0,0 +1,10 @@
|
||||
package slgui.themes;
|
||||
|
||||
public enum PanelMode {
|
||||
HIDDEN,
|
||||
AUTO_BOTTOM_LEFT,
|
||||
AUTO_BOTTOM_RIGHT,
|
||||
BOTTOM,
|
||||
LEFT,
|
||||
RIGHT
|
||||
}
|
7
src/slgui/themes/SpecialButtonType.java
Normal file
7
src/slgui/themes/SpecialButtonType.java
Normal file
@ -0,0 +1,7 @@
|
||||
package slgui.themes;
|
||||
|
||||
public enum SpecialButtonType {
|
||||
BLANK,
|
||||
CLOSE,
|
||||
HOME
|
||||
}
|
6
src/slgui/themes/StatusMode.java
Normal file
6
src/slgui/themes/StatusMode.java
Normal file
@ -0,0 +1,6 @@
|
||||
package slgui.themes;
|
||||
|
||||
public enum StatusMode {
|
||||
HIDDEN,
|
||||
TOP
|
||||
}
|
225
src/slgui/themes/Theme.java
Normal file
225
src/slgui/themes/Theme.java
Normal file
@ -0,0 +1,225 @@
|
||||
package slgui.themes;
|
||||
|
||||
import slgui.base.MediaBox;
|
||||
import slgui.base.MediaFont;
|
||||
import slgui.base.MediaInputState;
|
||||
import slgui.base.MediaPainter;
|
||||
import slgui.base.MediaPointerButton;
|
||||
import slgui.gfx.Painter;
|
||||
|
||||
public class Theme {
|
||||
|
||||
public Theme() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public MediaFont getFont() {
|
||||
return new MediaFont(2);
|
||||
}
|
||||
|
||||
public int getBorderPixel() {
|
||||
return 0xFF808080;
|
||||
}
|
||||
|
||||
public void paintSpecialButton(MediaPainter p, MediaInputState input, SpecialButtonType t, double x, double y, double width, double height, ButtonState overrideState) {
|
||||
if (overrideState == null) {
|
||||
overrideState = ButtonState.INACTIVE;
|
||||
if (input != null) {
|
||||
if (input.downWithin(MediaPointerButton.MAIN, x, y, width, height)) {
|
||||
overrideState = ButtonState.ACTIVE;
|
||||
} else if (input.hoverWithin(x, y, width, height)) {
|
||||
overrideState = ButtonState.HOVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
p.box(x, y, width, height, overrideState == ButtonState.ACTIVE ? 0xFFFFC050 : (overrideState == ButtonState.HOVER ? 0xFF50FFC0 : 0xFFFFFFFF));
|
||||
p.line(x, y, x + width, y, getBorderPixel(), 1.0);
|
||||
p.line(x, y+height, x + width, y+height, getBorderPixel(), 1.0);
|
||||
p.line(x, y, x, y + height, getBorderPixel(), 1.0);
|
||||
p.line(x + width, y, x + width, y + height, getBorderPixel(), 1.0);
|
||||
|
||||
switch (t) {
|
||||
case BLANK:
|
||||
break;
|
||||
case CLOSE:
|
||||
p.line(x, y, x+width,y+height, getBorderPixel(), 1.0);
|
||||
p.line(x, y+height, x+width,y, getBorderPixel(), 1.0);
|
||||
break;
|
||||
default:
|
||||
p.line(x, y, x+width,y+height, 0xFFFF0000, 1.0);
|
||||
p.line(x, y+height, x+width,y, 0xFFFF0000, 1.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void paintButton(MediaPainter p, MediaInputState input, String label, double x, double y, double width, double height) {
|
||||
paintSpecialButton(p, input, SpecialButtonType.BLANK, x, y, width, height, input.keypadDown(label.toUpperCase()) ? ButtonState.ACTIVE : null);
|
||||
getFont().render(p, label, x + (width/2) - ((4 + label.length()*16)/2), y + (height/2) - 8, 0xFF0000FF);
|
||||
}
|
||||
|
||||
public void paintWindowBorder(MediaPainter p, MediaInputState input, String title, double x, double y, double width, double height) {
|
||||
int topcolour;
|
||||
if (input != null && input.hoverWithin(x, y, width, 24)) {
|
||||
topcolour = 0xF0FFC050;
|
||||
} else {
|
||||
topcolour = 0xE0E0FFE0;
|
||||
}
|
||||
p.box(x, y, width, 24, topcolour);
|
||||
p.line(x, y, x + width, y, getBorderPixel(), 1.0);
|
||||
p.line(x, y+24, x + width, y+24, getBorderPixel(), 1.0);
|
||||
p.line(x, y+height, x + width, y+height, getBorderPixel(), 1.0);
|
||||
p.line(x, y, x, y + height, getBorderPixel(), 1.0);
|
||||
p.line(x + width, y, x + width, y + height, getBorderPixel(), 1.0);
|
||||
p.line(x + width, y + height - 16, x + width - 16, y + height, getBorderPixel(), 1.0);
|
||||
getFont().render(p, title, x + 24, y + 4, 0xFF0000FF);
|
||||
}
|
||||
|
||||
public void paintDemoWindow(MediaPainter p, MediaInputState input, String title, double x, double y, double width, double height) {
|
||||
paintWindowBorder(p, input, title, x, y, width, height);
|
||||
paintSpecialButton(p, input, SpecialButtonType.BLANK, x + 4, y + 4, 16, 16, null);
|
||||
paintSpecialButton(p, input, SpecialButtonType.CLOSE, x + width - 20, y + 4, 16, 16, null);
|
||||
}
|
||||
|
||||
public MediaBox desktopContentArea(MediaPainter p, double x, double y, double width, double height, KeypadType keypad, double keypadratio, StatusMode statusMode, PanelMode panelMode) {
|
||||
if (keypadratio < 0) {
|
||||
keypadratio = 0;
|
||||
} else if (keypadratio > 1) {
|
||||
keypadratio = 1;
|
||||
}
|
||||
if (keypad != KeypadType.NONE) {
|
||||
double kph = height/3;
|
||||
double kpw = 2*width/3;
|
||||
double kpx = x + (width/2) - (kpw/2);
|
||||
double kpy = y+height-40-(kph+1) + ((1.0-keypadratio)*(kph+100));
|
||||
//paintKeypad(p, keypad, kpx, kpy, kpw, kph, 100);
|
||||
return new MediaBox(x+0, y+24, width, Math.min(kpy-(y+24), height-(24+40)));
|
||||
} else {
|
||||
return new MediaBox(x+0, y+24, width, height-(24+40));
|
||||
}
|
||||
}
|
||||
|
||||
public void paintDesktopControls(MediaPainter p, MediaInputState input, String status1, String status2, double x, double y, double width, double height, KeypadType keypad, double keypadratio, StatusMode statusMode, PanelMode panelMode) {
|
||||
p.box(x, y, width, 24, 0xDDFFFFFF);
|
||||
//p.line(x, y, x + width, y, getBorderPixel(), 1.0);
|
||||
p.line(x, y+24, x + width, y+24, getBorderPixel(), 1.0);
|
||||
//p.line(x, y+height, x + width, y+height, getBorderPixel(), 1.0);
|
||||
//p.line(x, y, x, y + height, getBorderPixel(), 1.0);
|
||||
for (int i = 0; i*2 < 40; i++) {
|
||||
p.box(x, y+height-(40-i*2), width, 42-i*2, 0x40000000);//0x40FFFFFF);
|
||||
}
|
||||
p.line(x, y+height-40, x + width, y+height-40, getBorderPixel(), 1.0);
|
||||
//p.line(x + width, y, x + width, y + height, getBorderPixel(), 1.0);
|
||||
getFont().render(p, status1, x + 24, y + 4, 0xFF0000FF);
|
||||
getFont().render(p, status2, x + width - (4 + status2.length()*16), y + 4, 0xFF0000FF);
|
||||
}
|
||||
|
||||
public void paintDemoDesktop(MediaPainter p, MediaInputState input, String status1, String status2, double x, double y, double width, double height, KeypadType keypad, double keypadratio, StatusMode statusMode, PanelMode panelMode) {
|
||||
if (keypadratio < 0) {
|
||||
keypadratio = 0;
|
||||
} else if (keypadratio > 1) {
|
||||
keypadratio = 1;
|
||||
}
|
||||
if (keypad != KeypadType.NONE) {
|
||||
double kph = height/3;
|
||||
double kpw = 2*width/3;
|
||||
double kpx = x + (width/2) - (kpw/2);
|
||||
double kpy = y+height-40-(kph+1) + ((1.0-keypadratio)*(kph+100));
|
||||
paintKeypad(p, input, keypad, kpx, kpy, kpw, kph, 100);
|
||||
}
|
||||
paintDesktopControls(p, input, status1, status2, x, y, width, height, keypad, keypadratio, statusMode, panelMode);
|
||||
paintSpecialButton(p, input, SpecialButtonType.BLANK, x + 4, y + 4, 16, 16, null);
|
||||
paintSpecialButton(p, input, SpecialButtonType.HOME, x + (width/2) - 16, y + height - 36, 32, 32, null);
|
||||
paintSpecialButton(p, input, SpecialButtonType.HOME, x + (width/2) - 56, y + height - 36, 32, 32, null);
|
||||
paintSpecialButton(p, input, SpecialButtonType.HOME, x + (width/2) + 24, y + height - 36, 32, 32, null);
|
||||
}
|
||||
|
||||
public void paintKeypad(MediaPainter p, MediaInputState input, KeypadType t, double x, double y, double width, double height, double xheight) {
|
||||
p.box(x, y, width, height+xheight, 0xDDFFFFFF);
|
||||
p.line(x, y, x + width, y, getBorderPixel(), 1.0);
|
||||
p.line(x, y+height+xheight, x + width, y+height+xheight, getBorderPixel(), 1.0);
|
||||
p.line(x, y, x, y + height+xheight, getBorderPixel(), 1.0);
|
||||
p.line(x + width, y, x + width, y + height+xheight, getBorderPixel(), 1.0);
|
||||
|
||||
switch(t) {
|
||||
case NUMBERS:
|
||||
paintNumpad(p, input, x, y, width, height);
|
||||
break;
|
||||
case LATIN_UPPER:
|
||||
paintLatinKeypad(p, input, x, y, width, height, true);
|
||||
break;
|
||||
case LATIN_LOWER:
|
||||
paintLatinKeypad(p, input, x, y, width, height, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void paintNumpad(MediaPainter p, MediaInputState input, double x, double y, double width, double height) {
|
||||
double spc = (width+height)/50;
|
||||
double w = (width - spc*4)/3;
|
||||
double h = (height - spc*5)/4;
|
||||
|
||||
paintButton(p, input, "1", x+spc, y+spc, w, h);
|
||||
paintButton(p, input, "2", x+spc+w+spc, y+spc, w, h);
|
||||
paintButton(p, input, "3", x+spc+(w+spc)*2, y+spc, w, h);
|
||||
|
||||
paintButton(p, input, "4", x+spc, y+spc+(h+spc), w, h);
|
||||
paintButton(p, input, "5", x+spc+w+spc, y+spc+(h+spc), w, h);
|
||||
paintButton(p, input, "6", x+spc+(w+spc)*2, y+spc+(h+spc), w, h);
|
||||
|
||||
paintButton(p, input, "7", x+spc, y+spc+(h+spc)*2, w, h);
|
||||
paintButton(p, input, "8", x+spc+w+spc, y+spc+(h+spc)*2, w, h);
|
||||
paintButton(p, input, "9", x+spc+(w+spc)*2, y+spc+(h+spc)*2, w, h);
|
||||
|
||||
//paintButton(p, "7", x+spc, y+spc+(h+spc)*3, w, h);
|
||||
paintButton(p, input, "0", x+spc+w+spc, y+spc+(h+spc)*3, w, h);
|
||||
//paintButton(p, "9", x+spc+(w+spc)*2, y+spc+(h+spc)*3, w, h);
|
||||
}
|
||||
|
||||
public String recase(String input, boolean upcase) {
|
||||
if (upcase) {
|
||||
return input.toUpperCase();
|
||||
} else {
|
||||
return input.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
public void paintKeypadRow(MediaPainter p, MediaInputState input, double x, double y, double width, double height, boolean upcase, double spc, double bw, double bh, String...strings) {
|
||||
x = (x + width/2) - ((strings.length*bw + (strings.length-1)*spc)/2);
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
String s = recase(strings[i], upcase);
|
||||
double bx = x + (i * (bw + spc));
|
||||
double by = y + spc;
|
||||
paintButton(p, input, s, bx, by, bw, bh);
|
||||
}
|
||||
}
|
||||
|
||||
public void paintLatinKeypad(MediaPainter p, MediaInputState input, double x, double y, double width, double height, boolean upcase) {
|
||||
double spc = 8;//(width+height)/50;
|
||||
double w = (width - spc*11)/10;
|
||||
double h = (height - spc*5)/4;
|
||||
|
||||
paintKeypadRow(p, input, x, y, width, height, upcase, spc, w, h, "q", "w", "e", "r", "t", "y", "u", "i", "o", "p");
|
||||
paintKeypadRow(p, input, x, y+(h+spc), width, height, upcase, spc, w, h, "a", "s", "d", "f", "g", "h", "j", "k", "l");
|
||||
paintKeypadRow(p, input, x, y+(h+spc)*2, width, height, upcase, spc, w, h, "z", "x", "c", "v", "b", "n", "m");
|
||||
|
||||
double spcw = w*3+spc*2;
|
||||
paintButton(p, input, " ", x + width/2 - spcw/2, y+spc+(h+spc)*3, spcw, h);
|
||||
|
||||
/*paintButton(p, "1", x+spc, y+spc, w, h);
|
||||
paintButton(p, "2", x+spc+w+spc, y+spc, w, h);
|
||||
paintButton(p, "3", x+spc+(w+spc)*2, y+spc, w, h);
|
||||
|
||||
paintButton(p, "4", x+spc, y+spc+(h+spc), w, h);
|
||||
paintButton(p, "5", x+spc+w+spc, y+spc+(h+spc), w, h);
|
||||
paintButton(p, "6", x+spc+(w+spc)*2, y+spc+(h+spc), w, h);
|
||||
|
||||
paintButton(p, "7", x+spc, y+spc+(h+spc)*2, w, h);
|
||||
paintButton(p, "8", x+spc+w+spc, y+spc+(h+spc)*2, w, h);
|
||||
paintButton(p, "9", x+spc+(w+spc)*2, y+spc+(h+spc)*2, w, h);
|
||||
|
||||
//paintButton(p, "7", x+spc, y+spc+(h+spc)*3, w, h);
|
||||
paintButton(p, "0", x+spc+w+spc, y+spc+(h+spc)*3, w, h);
|
||||
//paintButton(p, "9", x+spc+(w+spc)*2, y+spc+(h+spc)*3, w, h);
|
||||
*/
|
||||
}
|
||||
}
|
64
src/slgui/views/View.java
Normal file
64
src/slgui/views/View.java
Normal file
@ -0,0 +1,64 @@
|
||||
package slgui.views;
|
||||
|
||||
import slgui.gfx.Painter;
|
||||
import slgui.themes.Theme;
|
||||
|
||||
public abstract class View {
|
||||
private View outer;
|
||||
private View[] inners = null;
|
||||
|
||||
public abstract void paint(Painter painter, Theme theme);
|
||||
|
||||
public View outer() {
|
||||
return outer;
|
||||
}
|
||||
|
||||
public View inner(int i) {
|
||||
return inners[i];
|
||||
}
|
||||
|
||||
public int innerIndex(View v) {
|
||||
for (int i = 0; i < inners(); i++) {
|
||||
if (inner(i) == v) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int inners() {
|
||||
return inners.length;
|
||||
}
|
||||
|
||||
public void addView(View v) {
|
||||
View[] newInners = new View[inners() + 1];
|
||||
|
||||
for (int i = 0; i < newInners.length; i++) {
|
||||
if (i < inners()) {
|
||||
newInners[i] = inner(i);
|
||||
} else {
|
||||
newInners[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
inners = newInners;
|
||||
}
|
||||
|
||||
public void removeView(View v) {
|
||||
int idx = innerIndex(v);
|
||||
if (idx >= 0) {
|
||||
View[] newInners = new View[inners() - 1];
|
||||
|
||||
for (int i = 0; i < newInners.length; i++) {
|
||||
if (i < idx) {
|
||||
newInners[i] = inner(i);
|
||||
} else {
|
||||
newInners[i] = inner(i+1);
|
||||
}
|
||||
}
|
||||
|
||||
inners = newInners;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user