Browse Source

Added output view

Stan Hebben 6 years ago
parent
commit
58c1bbbc5e
34 changed files with 333 additions and 205 deletions
  1. 3
    2
      CompilerShared/src/main/java/org/openzen/zenscript/compiler/SemanticModule.java
  2. 3
    3
      Constructor/src/main/java/org/openzen/zenscript/constructor/Library.java
  3. 10
    5
      Constructor/src/main/java/org/openzen/zenscript/constructor/Main.java
  4. 10
    6
      Constructor/src/main/java/org/openzen/zenscript/constructor/Module.java
  5. 6
    2
      Constructor/src/main/java/org/openzen/zenscript/constructor/ModuleLoader.java
  6. 7
    5
      Constructor/src/main/java/org/openzen/zenscript/constructor/Project.java
  7. 7
    7
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java
  8. 4
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/ModuleReference.java
  9. 1
    5
      DrawableGui/src/main/java/org/openzen/drawablegui/DComponent.java
  10. 4
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/DFontMetrics.java
  11. 2
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/DSimpleTooltipComponent.java
  12. 22
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/Destructible.java
  13. 2
    5
      DrawableGui/src/main/java/org/openzen/drawablegui/draw/DDrawnElement.java
  14. 2
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveConcatList.java
  15. 2
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveMappedList.java
  16. 2
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LivePredicateBool.java
  17. 17
    103
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java
  18. 4
    3
      DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingSubSurface.java
  19. 4
    3
      DrawableGui/src/main/java/org/openzen/drawablegui/tree/DTreeView.java
  20. 1
    4
      IDE/src/main/java/org/openzen/zenscript/ide/Main.java
  21. 5
    2
      IDE/src/main/java/org/openzen/zenscript/ide/host/IDETarget.java
  22. 39
    17
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java
  23. 21
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEStyling.java
  24. 6
    2
      IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEWindow.java
  25. 0
    3
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabClose.java
  26. 17
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/WindowView.java
  27. 10
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/BasicOutputSpan.java
  28. 12
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/ErrorOutputSpan.java
  29. 8
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputLine.java
  30. 2
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputSpan.java
  31. 81
    2
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputView.java
  32. 4
    13
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputViewStyle.java
  33. 12
    4
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/project/ProjectBrowser.java
  34. 3
    1
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java

+ 3
- 2
CompilerShared/src/main/java/org/openzen/zenscript/compiler/SemanticModule.java View File

9
 import java.util.HashMap;
9
 import java.util.HashMap;
10
 import java.util.List;
10
 import java.util.List;
11
 import java.util.Map;
11
 import java.util.Map;
12
+import java.util.function.Consumer;
12
 import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
13
 import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
14
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
14
 import org.openzen.zenscript.codemodel.PackageDefinitions;
15
 import org.openzen.zenscript.codemodel.PackageDefinitions;
93
 				annotations);
94
 				annotations);
94
 	}
95
 	}
95
 	
96
 	
96
-	public boolean validate() {
97
+	public boolean validate(Consumer<ValidationLogEntry> logger) {
97
 		if (state != State.NORMALIZED)
98
 		if (state != State.NORMALIZED)
98
 			throw new IllegalStateException("Module is not yet normalized");
99
 			throw new IllegalStateException("Module is not yet normalized");
99
 		
100
 		
106
 		}
107
 		}
107
 		
108
 		
108
 		for (ValidationLogEntry entry : validator.getLog()) {
109
 		for (ValidationLogEntry entry : validator.getLog()) {
109
-			System.out.println(entry.kind + " " + entry.position.toString() + ": " + entry.message);
110
+			logger.accept(entry);
110
 		}
111
 		}
111
 		state = validator.hasErrors() ? State.INVALID : State.VALIDATED;
112
 		state = validator.hasErrors() ? State.INVALID : State.VALIDATED;
112
 		return !validator.hasErrors();
113
 		return !validator.hasErrors();

+ 3
- 3
Constructor/src/main/java/org/openzen/zenscript/constructor/Library.java View File

8
 import java.io.File;
8
 import java.io.File;
9
 import org.json.JSONArray;
9
 import org.json.JSONArray;
10
 import org.json.JSONObject;
10
 import org.json.JSONObject;
11
-import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
11
+import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
12
 import org.openzen.zenscript.constructor.module.ModuleReference;
12
 import org.openzen.zenscript.constructor.module.ModuleReference;
13
 
13
 
14
 /**
14
 /**
20
 	public final File directory;
20
 	public final File directory;
21
 	public final ModuleReference[] modules;
21
 	public final ModuleReference[] modules;
22
 	
22
 	
23
-	public Library(ModuleLoader loader, File directory, String name, JSONObject json) {
23
+	public Library(File directory, String name, JSONObject json) {
24
 		this.name = name;
24
 		this.name = name;
25
 		this.directory = new File(directory, json.getString("directory"));
25
 		this.directory = new File(directory, json.getString("directory"));
26
 		
26
 		
28
 		modules = new ModuleReference[modulesJson.length()];
28
 		modules = new ModuleReference[modulesJson.length()];
29
 		for (int i = 0; i < modulesJson.length(); i++) {
29
 		for (int i = 0; i < modulesJson.length(); i++) {
30
 			String moduleName = modulesJson.getString(i);
30
 			String moduleName = modulesJson.getString(i);
31
-			modules[i] = new DirectoryModuleLoader(loader, moduleName, new File(this.directory, moduleName), false);
31
+			modules[i] = new DirectoryModuleReference(moduleName, new File(this.directory, moduleName), false);
32
 		}
32
 		}
33
 	}
33
 	}
34
 }
34
 }

+ 10
- 5
Constructor/src/main/java/org/openzen/zenscript/constructor/Main.java View File

1
 package org.openzen.zenscript.constructor;
1
 package org.openzen.zenscript.constructor;
2
 
2
 
3
-import org.openzen.zenscript.compiler.CompilationUnit;
4
 import java.io.File;
3
 import java.io.File;
4
+import org.openzen.zenscript.compiler.CompilationUnit;
5
 import java.io.IOException;
5
 import java.io.IOException;
6
-import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
6
+import java.util.function.Consumer;
7
+import org.openzen.zencode.shared.CompileException;
8
+import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
7
 import org.openzen.zenscript.constructor.module.ModuleReference;
9
 import org.openzen.zenscript.constructor.module.ModuleReference;
8
 
10
 
9
 public class Main {
11
 public class Main {
18
 			return;
20
 			return;
19
 		}
21
 		}
20
 		
22
 		
23
+		Consumer<CompileException> exceptionLogger = exception -> System.err.println(exception.toString());
24
+		
21
 		File currentDirectory = new File(arguments.directory);
25
 		File currentDirectory = new File(arguments.directory);
22
 		CompilationUnit compilationUnit = new CompilationUnit();
26
 		CompilationUnit compilationUnit = new CompilationUnit();
23
-		ModuleLoader moduleLoader = new ModuleLoader(compilationUnit);
24
-		moduleLoader.register("stdlib", new DirectoryModuleLoader(moduleLoader, "stdlib", new File("../../StdLibs/stdlib"), true));
25
 		
27
 		
26
-		Project project = new Project(moduleLoader, currentDirectory);
28
+		ModuleLoader moduleLoader = new ModuleLoader(compilationUnit, exceptionLogger);
29
+		moduleLoader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
30
+		
31
+		Project project = new Project(currentDirectory);
27
 		for (Library library : project.libraries) {
32
 		for (Library library : project.libraries) {
28
 			for (ModuleReference module : library.modules)
33
 			for (ModuleReference module : library.modules)
29
 				moduleLoader.register(module.getName(), module);
34
 				moduleLoader.register(module.getName(), module);

+ 10
- 6
Constructor/src/main/java/org/openzen/zenscript/constructor/Module.java View File

13
 import java.util.Collections;
13
 import java.util.Collections;
14
 import java.util.List;
14
 import java.util.List;
15
 import java.util.Map;
15
 import java.util.Map;
16
+import java.util.function.Consumer;
16
 import org.json.JSONArray;
17
 import org.json.JSONArray;
17
 import org.json.JSONObject;
18
 import org.json.JSONObject;
18
 import org.json.JSONTokener;
19
 import org.json.JSONTokener;
36
 	public final File sourceDirectory;
37
 	public final File sourceDirectory;
37
 	public final String packageName;
38
 	public final String packageName;
38
 	public final String host;
39
 	public final String host;
40
+	private final Consumer<CompileException> exceptionLogger;
39
 	
41
 	
40
-	public Module(String name, File directory, File moduleFile) throws IOException {
42
+	public Module(String name, File directory, File moduleFile, Consumer<CompileException> exceptionLogger) throws IOException {
41
 		this.name = name;
43
 		this.name = name;
42
 		this.sourceDirectory = new File(directory, "src");
44
 		this.sourceDirectory = new File(directory, "src");
45
+		this.exceptionLogger = exceptionLogger;
43
 		
46
 		
44
 		BufferedInputStream input = new BufferedInputStream(new FileInputStream(moduleFile));
47
 		BufferedInputStream input = new BufferedInputStream(new FileInputStream(moduleFile));
45
 		JSONObject json = new JSONObject(new JSONTokener(input));
48
 		JSONObject json = new JSONObject(new JSONTokener(input));
67
 				try {
70
 				try {
68
 					files.add(ParsedFile.parse(pkg, file));
71
 					files.add(ParsedFile.parse(pkg, file));
69
 				} catch (CompileException ex) {
72
 				} catch (CompileException ex) {
70
-					System.out.println(ex.getMessage());
73
+					exceptionLogger.accept(ex);
71
 				}
74
 				}
72
 			} else if (file.isDirectory()) {
75
 			} else if (file.isDirectory()) {
73
 				parse(files, pkg.getOrCreatePackage(file.getName()), file);
76
 				parse(files, pkg.getOrCreatePackage(file.getName()), file);
80
 			String[] dependencies,
83
 			String[] dependencies,
81
 			ZSPackage pkg,
84
 			ZSPackage pkg,
82
 			ParsedFile[] files,
85
 			ParsedFile[] files,
83
-			ModuleSpace registry) {
86
+			ModuleSpace registry,
87
+			Consumer<CompileException> exceptionLogger) {
84
 		// We are considering all these files to be in the same package, so make
88
 		// We are considering all these files to be in the same package, so make
85
 		// a single PackageDefinition instance. If these files were in multiple
89
 		// a single PackageDefinition instance. If these files were in multiple
86
 		// packages, we'd need an instance for every package.
90
 		// packages, we'd need an instance for every package.
106
 			try {
110
 			try {
107
 				file.compileTypes(rootPackage, pkg, definitions, registry.compilationUnit.globalTypeRegistry, expansions, globals, registry.getAnnotations());
111
 				file.compileTypes(rootPackage, pkg, definitions, registry.compilationUnit.globalTypeRegistry, expansions, globals, registry.getAnnotations());
108
 			} catch (CompileException ex) {
112
 			} catch (CompileException ex) {
109
-				System.out.println(ex.getMessage());
113
+				exceptionLogger.accept(ex);
110
 				failed = true;
114
 				failed = true;
111
 			}
115
 			}
112
 		}
116
 		}
121
 			try {
125
 			try {
122
 				file.compileMembers(rootPackage, pkg, definitions, registry.compilationUnit.globalTypeRegistry, expansions, globals, registry.getAnnotations());
126
 				file.compileMembers(rootPackage, pkg, definitions, registry.compilationUnit.globalTypeRegistry, expansions, globals, registry.getAnnotations());
123
 			} catch (CompileException ex) {
127
 			} catch (CompileException ex) {
124
-				System.out.println(ex.getMessage());
128
+				exceptionLogger.accept(ex);
125
 				failed = true;
129
 				failed = true;
126
 			}
130
 			}
127
 		}
131
 		}
138
 			try {
142
 			try {
139
 				file.compileCode(rootPackage, pkg, definitions, registry.compilationUnit.globalTypeRegistry, expansions, scripts, globals, registry.getAnnotations());
143
 				file.compileCode(rootPackage, pkg, definitions, registry.compilationUnit.globalTypeRegistry, expansions, scripts, globals, registry.getAnnotations());
140
 			} catch (CompileException ex) {
144
 			} catch (CompileException ex) {
141
-				System.out.println(ex.getMessage());
145
+				exceptionLogger.accept(ex);
142
 				failed = true;
146
 				failed = true;
143
 			}
147
 			}
144
 		}
148
 		}

+ 6
- 2
Constructor/src/main/java/org/openzen/zenscript/constructor/ModuleLoader.java View File

10
 import java.util.HashSet;
10
 import java.util.HashSet;
11
 import java.util.Map;
11
 import java.util.Map;
12
 import java.util.Stack;
12
 import java.util.Stack;
13
+import java.util.function.Consumer;
14
+import org.openzen.zencode.shared.CompileException;
13
 import org.openzen.zenscript.constructor.module.ModuleReference;
15
 import org.openzen.zenscript.constructor.module.ModuleReference;
14
 import org.openzen.zenscript.compiler.SemanticModule;
16
 import org.openzen.zenscript.compiler.SemanticModule;
15
 
17
 
25
 	private final Stack<String> compilingModulesStack = new Stack<>();
27
 	private final Stack<String> compilingModulesStack = new Stack<>();
26
 	
28
 	
27
 	private final CompilationUnit compilationUnit;
29
 	private final CompilationUnit compilationUnit;
30
+	private final Consumer<CompileException> exceptionLogger;
28
 	
31
 	
29
-	public ModuleLoader(CompilationUnit compilationUnit) {
32
+	public ModuleLoader(CompilationUnit compilationUnit, Consumer<CompileException> exceptionLogger) {
30
 		this.compilationUnit = compilationUnit;
33
 		this.compilationUnit = compilationUnit;
34
+		this.exceptionLogger = exceptionLogger;
31
 	}
35
 	}
32
 	
36
 	
33
 	public SemanticModule getModule(String name) {
37
 	public SemanticModule getModule(String name) {
49
 		compilingModulesSet.add(name);
53
 		compilingModulesSet.add(name);
50
 		compilingModulesStack.add(name);
54
 		compilingModulesStack.add(name);
51
 		
55
 		
52
-		SemanticModule module = modules.get(name).load(compilationUnit);
56
+		SemanticModule module = modules.get(name).load(this, compilationUnit, exceptionLogger);
53
 		moduleCache.put(name, module);
57
 		moduleCache.put(name, module);
54
 		
58
 		
55
 		compilingModulesSet.remove(name);
59
 		compilingModulesSet.remove(name);

+ 7
- 5
Constructor/src/main/java/org/openzen/zenscript/constructor/Project.java View File

9
 import java.io.IOException;
9
 import java.io.IOException;
10
 import java.util.ArrayList;
10
 import java.util.ArrayList;
11
 import java.util.List;
11
 import java.util.List;
12
+import java.util.function.Consumer;
12
 import org.json.JSONArray;
13
 import org.json.JSONArray;
13
 import org.json.JSONObject;
14
 import org.json.JSONObject;
14
-import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
15
+import org.openzen.zencode.shared.CompileException;
16
+import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
15
 import org.openzen.zenscript.constructor.module.ModuleReference;
17
 import org.openzen.zenscript.constructor.module.ModuleReference;
16
 import org.openzen.zenscript.compiler.Target;
18
 import org.openzen.zenscript.compiler.Target;
17
 import org.openzen.zenscript.compiler.TargetType;
19
 import org.openzen.zenscript.compiler.TargetType;
27
 	public final Library[] libraries;
29
 	public final Library[] libraries;
28
 	public final Target[] targets;
30
 	public final Target[] targets;
29
 	
31
 	
30
-	public Project(ModuleLoader loader, File directory) throws IOException {
32
+	public Project(File directory) throws IOException {
31
 		this.directory = directory;
33
 		this.directory = directory;
32
 		name = directory.getName();
34
 		name = directory.getName();
33
 		
35
 		
46
 		libraries = new Library[jsonLibraries.length()];
48
 		libraries = new Library[jsonLibraries.length()];
47
 		int k = 0;
49
 		int k = 0;
48
 		for (String key : jsonLibraries.keySet()) {
50
 		for (String key : jsonLibraries.keySet()) {
49
-			libraries[k] = new Library(loader, directory, key, jsonLibraries.getJSONObject(key));
51
+			libraries[k] = new Library(directory, key, jsonLibraries.getJSONObject(key));
50
 			k++;
52
 			k++;
51
 		}
53
 		}
52
 		
54
 		
55
 		for (int i = 0; i < jsonModules.length(); i++) {
57
 		for (int i = 0; i < jsonModules.length(); i++) {
56
 			Object module = jsonModules.get(i);
58
 			Object module = jsonModules.get(i);
57
 			if (module instanceof String) {
59
 			if (module instanceof String) {
58
-				modules[i] = new DirectoryModuleLoader(loader, module.toString(), new File(directory, module.toString()), false);
60
+				modules[i] = new DirectoryModuleReference(module.toString(), new File(directory, module.toString()), false);
59
 			} else if (module instanceof JSONObject) {
61
 			} else if (module instanceof JSONObject) {
60
 				JSONObject jsonModule = (JSONObject) module;
62
 				JSONObject jsonModule = (JSONObject) module;
61
 				String name = jsonModule.getString("name");
63
 				String name = jsonModule.getString("name");
62
 				switch (jsonModule.getString("type")) {
64
 				switch (jsonModule.getString("type")) {
63
 					case "directory":
65
 					case "directory":
64
-						modules[i] = new DirectoryModuleLoader(loader, name, new File(directory, jsonModule.getString("directory")), false);
66
+						modules[i] = new DirectoryModuleReference(name, new File(directory, jsonModule.getString("directory")), false);
65
 						break;
67
 						break;
66
 					default:
68
 					default:
67
 						throw new ConstructorException("Invalid module type: " + jsonModule.getString("type"));
69
 						throw new ConstructorException("Invalid module type: " + jsonModule.getString("type"));

Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleLoader.java → Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java View File

10
 import java.io.IOException;
10
 import java.io.IOException;
11
 import java.util.ArrayList;
11
 import java.util.ArrayList;
12
 import java.util.List;
12
 import java.util.List;
13
+import java.util.function.Consumer;
13
 import org.json.JSONArray;
14
 import org.json.JSONArray;
14
 import org.json.JSONObject;
15
 import org.json.JSONObject;
16
+import org.openzen.zencode.shared.CompileException;
15
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
17
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
16
 import org.openzen.zenscript.compiler.CompilationUnit;
18
 import org.openzen.zenscript.compiler.CompilationUnit;
17
 import org.openzen.zenscript.constructor.ConstructorException;
19
 import org.openzen.zenscript.constructor.ConstructorException;
25
  *
27
  *
26
  * @author Hoofdgebruiker
28
  * @author Hoofdgebruiker
27
  */
29
  */
28
-public class DirectoryModuleLoader implements ModuleReference {
29
-	private final ModuleLoader loader;
30
+public class DirectoryModuleReference implements ModuleReference {
30
 	private final String moduleName;
31
 	private final String moduleName;
31
 	private final File directory;
32
 	private final File directory;
32
 	private final boolean isStdlib;
33
 	private final boolean isStdlib;
33
 	private SourcePackage rootPackage = null;
34
 	private SourcePackage rootPackage = null;
34
 	
35
 	
35
-	public DirectoryModuleLoader(ModuleLoader loader, String moduleName, File directory, boolean isStdlib) {
36
-		this.loader = loader;
36
+	public DirectoryModuleReference(String moduleName, File directory, boolean isStdlib) {
37
 		this.moduleName = moduleName;
37
 		this.moduleName = moduleName;
38
 		this.directory = directory;
38
 		this.directory = directory;
39
 		this.isStdlib = isStdlib;
39
 		this.isStdlib = isStdlib;
45
 	}
45
 	}
46
 
46
 
47
 	@Override
47
 	@Override
48
-	public SemanticModule load(CompilationUnit unit) {
48
+	public SemanticModule load(ModuleLoader loader, CompilationUnit unit, Consumer<CompileException> exceptionLogger) {
49
 		if (!directory.exists())
49
 		if (!directory.exists())
50
 			throw new ConstructorException("Error: module directory not found: " + directory);
50
 			throw new ConstructorException("Error: module directory not found: " + directory);
51
 		
51
 		
71
 			for (String dependencyName : dependencyNames)
71
 			for (String dependencyName : dependencyNames)
72
 				space.addModule(dependencyName, loader.getModule(dependencyName));
72
 				space.addModule(dependencyName, loader.getModule(dependencyName));
73
 
73
 
74
-			Module module = new Module(moduleName, directory, jsonFile);
74
+			Module module = new Module(moduleName, directory, jsonFile, exceptionLogger);
75
 			ZSPackage pkg = isStdlib ? unit.globalTypeRegistry.stdlib : new ZSPackage(null, module.packageName);
75
 			ZSPackage pkg = isStdlib ? unit.globalTypeRegistry.stdlib : new ZSPackage(null, module.packageName);
76
 
76
 
77
 			ParsedFile[] parsedFiles = module.parse(pkg);
77
 			ParsedFile[] parsedFiles = module.parse(pkg);
78
-			SemanticModule result = Module.compileSyntaxToSemantic(module.name, module.dependencies, pkg, parsedFiles, space);
78
+			SemanticModule result = Module.compileSyntaxToSemantic(module.name, module.dependencies, pkg, parsedFiles, space, exceptionLogger);
79
 			
79
 			
80
 			JSONObject globals = json.optJSONObject("globals");
80
 			JSONObject globals = json.optJSONObject("globals");
81
 			if (globals != null) {
81
 			if (globals != null) {

+ 4
- 1
Constructor/src/main/java/org/openzen/zenscript/constructor/module/ModuleReference.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.constructor.module;
6
 package org.openzen.zenscript.constructor.module;
7
 
7
 
8
+import java.util.function.Consumer;
9
+import org.openzen.zencode.shared.CompileException;
8
 import org.openzen.zenscript.compiler.SemanticModule;
10
 import org.openzen.zenscript.compiler.SemanticModule;
9
 import org.openzen.zenscript.compiler.CompilationUnit;
11
 import org.openzen.zenscript.compiler.CompilationUnit;
12
+import org.openzen.zenscript.constructor.ModuleLoader;
10
 
13
 
11
 /**
14
 /**
12
  *
15
  *
15
 public interface ModuleReference {
18
 public interface ModuleReference {
16
 	public String getName();
19
 	public String getName();
17
 	
20
 	
18
-	public SemanticModule load(CompilationUnit unit);
21
+	public SemanticModule load(ModuleLoader loader, CompilationUnit unit, Consumer<CompileException> exceptionLogger);
19
 	
22
 	
20
 	public SourcePackage getRootPackage();
23
 	public SourcePackage getRootPackage();
21
 }
24
 }

+ 1
- 5
DrawableGui/src/main/java/org/openzen/drawablegui/DComponent.java View File

5
  */
5
  */
6
 package org.openzen.drawablegui;
6
 package org.openzen.drawablegui;
7
 
7
 
8
-import java.io.Closeable;
9
 import org.openzen.drawablegui.draw.DDrawSurface;
8
 import org.openzen.drawablegui.draw.DDrawSurface;
10
 import org.openzen.drawablegui.live.LiveObject;
9
 import org.openzen.drawablegui.live.LiveObject;
11
 import org.openzen.drawablegui.style.DStylePath;
10
 import org.openzen.drawablegui.style.DStylePath;
14
  *
13
  *
15
  * @author Hoofdgebruiker
14
  * @author Hoofdgebruiker
16
  */
15
  */
17
-public interface DComponent extends Closeable {
16
+public interface DComponent extends Destructible {
18
 	void mount(DStylePath parent, int z, DDrawSurface surface);
17
 	void mount(DStylePath parent, int z, DDrawSurface surface);
19
 	
18
 	
20
 	void unmount();
19
 	void unmount();
56
 	default void onKeyPressed(DKeyEvent e) {}
55
 	default void onKeyPressed(DKeyEvent e) {}
57
 	
56
 	
58
 	default void onKeyReleased(DKeyEvent e) {}
57
 	default void onKeyReleased(DKeyEvent e) {}
59
-	
60
-	@Override
61
-	void close();
62
 }
58
 }

+ 4
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/DFontMetrics.java View File

19
 	int getWidth(String str);
19
 	int getWidth(String str);
20
 	
20
 	
21
 	int getWidth(String str, int offset, int length);
21
 	int getWidth(String str, int offset, int length);
22
+	
23
+	default int getLineHeight() {
24
+		return getAscent() + getDescent();
25
+	}
22
 }
26
 }

+ 2
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/DSimpleTooltipComponent.java View File

101
 		fontMetrics = surface.getFontMetrics(style.font);
101
 		fontMetrics = surface.getFontMetrics(style.font);
102
 		calculateSize();
102
 		calculateSize();
103
 		
103
 		
104
+		if (text != null)
105
+			text.close();
104
 		text = surface.drawText(z + 1, style.font, style.textColor, 0, 0, tooltip.getValue());
106
 		text = surface.drawText(z + 1, style.font, style.textColor, 0, 0, tooltip.getValue());
105
 	}
107
 	}
106
 	
108
 	

+ 22
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/Destructible.java View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.drawablegui;
7
+
8
+import java.util.List;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public interface Destructible extends AutoCloseable {
15
+	public static <T extends Destructible> void close(List<T> list) {
16
+		for (T item : list)
17
+			item.close();
18
+	}
19
+	
20
+	@Override
21
+	public void close();
22
+}

+ 2
- 5
DrawableGui/src/main/java/org/openzen/drawablegui/draw/DDrawnElement.java View File

5
  */
5
  */
6
 package org.openzen.drawablegui.draw;
6
 package org.openzen.drawablegui.draw;
7
 
7
 
8
-import java.io.Closeable;
9
 import org.openzen.drawablegui.DIRectangle;
8
 import org.openzen.drawablegui.DIRectangle;
10
 import org.openzen.drawablegui.DTransform2D;
9
 import org.openzen.drawablegui.DTransform2D;
10
+import org.openzen.drawablegui.Destructible;
11
 
11
 
12
 /**
12
 /**
13
  *
13
  *
14
  * @author Hoofdgebruiker
14
  * @author Hoofdgebruiker
15
  */
15
  */
16
-public interface DDrawnElement extends Closeable {
16
+public interface DDrawnElement extends Destructible {
17
 	void setTransform(DTransform2D transform);
17
 	void setTransform(DTransform2D transform);
18
 	
18
 	
19
 	DIRectangle getBounds();
19
 	DIRectangle getBounds();
20
-	
21
-	@Override
22
-	public void close();
23
 }
20
 }

+ 2
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveConcatList.java View File

5
  */
5
  */
6
 package org.openzen.drawablegui.live;
6
 package org.openzen.drawablegui.live;
7
 
7
 
8
-import java.io.Closeable;
9
 import java.util.Iterator;
8
 import java.util.Iterator;
9
+import org.openzen.drawablegui.Destructible;
10
 import org.openzen.drawablegui.listeners.ListenerHandle;
10
 import org.openzen.drawablegui.listeners.ListenerHandle;
11
 import org.openzen.drawablegui.listeners.ListenerList;
11
 import org.openzen.drawablegui.listeners.ListenerList;
12
 
12
 
14
  *
14
  *
15
  * @author Hoofdgebruiker
15
  * @author Hoofdgebruiker
16
  */
16
  */
17
-public class LiveConcatList<T> implements Closeable, LiveList<T> {
17
+public class LiveConcatList<T> implements Destructible, LiveList<T> {
18
 	private final ListenerList<Listener<T>> listeners = new ListenerList<>();
18
 	private final ListenerList<Listener<T>> listeners = new ListenerList<>();
19
 	private final LiveList<T> a;
19
 	private final LiveList<T> a;
20
 	private final LiveList<T> b;
20
 	private final LiveList<T> b;

+ 2
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveMappedList.java View File

5
  */
5
  */
6
 package org.openzen.drawablegui.live;
6
 package org.openzen.drawablegui.live;
7
 
7
 
8
-import java.io.Closeable;
9
 import java.util.ArrayList;
8
 import java.util.ArrayList;
10
 import java.util.Iterator;
9
 import java.util.Iterator;
11
 import java.util.List;
10
 import java.util.List;
12
 import java.util.function.Function;
11
 import java.util.function.Function;
12
+import org.openzen.drawablegui.Destructible;
13
 import org.openzen.drawablegui.listeners.ListenerHandle;
13
 import org.openzen.drawablegui.listeners.ListenerHandle;
14
 import org.openzen.drawablegui.listeners.ListenerList;
14
 import org.openzen.drawablegui.listeners.ListenerList;
15
 
15
 
17
  *
17
  *
18
  * @author Hoofdgebruiker
18
  * @author Hoofdgebruiker
19
  */
19
  */
20
-public class LiveMappedList<T, U> implements Closeable, LiveList<U> {
20
+public class LiveMappedList<T, U> implements Destructible, LiveList<U> {
21
 	private final ListenerList<Listener<U>> listeners = new ListenerList<>();
21
 	private final ListenerList<Listener<U>> listeners = new ListenerList<>();
22
 	private final Function<T, U> projection;
22
 	private final Function<T, U> projection;
23
 	private final List<U> mapped;
23
 	private final List<U> mapped;

+ 2
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/live/LivePredicateBool.java View File

5
  */
5
  */
6
 package org.openzen.drawablegui.live;
6
 package org.openzen.drawablegui.live;
7
 
7
 
8
-import java.io.Closeable;
9
 import java.util.function.Predicate;
8
 import java.util.function.Predicate;
9
+import org.openzen.drawablegui.Destructible;
10
 import org.openzen.drawablegui.listeners.ListenerHandle;
10
 import org.openzen.drawablegui.listeners.ListenerHandle;
11
 import org.openzen.drawablegui.listeners.ListenerList;
11
 import org.openzen.drawablegui.listeners.ListenerList;
12
 
12
 
14
  *
14
  *
15
  * @author Hoofdgebruiker
15
  * @author Hoofdgebruiker
16
  */
16
  */
17
-public class LivePredicateBool<T> implements LiveBool, Closeable, LiveObject.Listener<T> {
17
+public class LivePredicateBool<T> implements LiveBool, Destructible, LiveObject.Listener<T> {
18
 	private final ListenerList<LiveBool.Listener> listeners = new ListenerList<>();
18
 	private final ListenerList<LiveBool.Listener> listeners = new ListenerList<>();
19
 	private final LiveObject<T> source;
19
 	private final LiveObject<T> source;
20
 	private final Predicate<T> predicate;
20
 	private final Predicate<T> predicate;

+ 17
- 103
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java View File

24
 import org.openzen.drawablegui.draw.DDrawSurface;
24
 import org.openzen.drawablegui.draw.DDrawSurface;
25
 import org.openzen.drawablegui.draw.DDrawnShape;
25
 import org.openzen.drawablegui.draw.DDrawnShape;
26
 import org.openzen.drawablegui.draw.DSubSurface;
26
 import org.openzen.drawablegui.draw.DSubSurface;
27
-import org.openzen.drawablegui.live.MutableLiveObject;
28
 import org.openzen.drawablegui.style.DStyleClass;
27
 import org.openzen.drawablegui.style.DStyleClass;
29
 import org.openzen.drawablegui.style.DStylePath;
28
 import org.openzen.drawablegui.style.DStylePath;
30
 import org.openzen.drawablegui.style.DStyleSheets;
29
 import org.openzen.drawablegui.style.DStyleSheets;
47
 	private final LiveInt offsetX;
46
 	private final LiveInt offsetX;
48
 	private final LiveInt offsetY;
47
 	private final LiveInt offsetY;
49
 	
48
 	
50
-	private final LiveInt preferredHeight;
51
-	private final MutableLiveObject<DSizing> sizing = DSizing.create();
49
+	private final LiveObject<DSizing> sizing;
52
 	
50
 	
53
 	private final ListenerHandle<LiveInt.Listener> contentsHeightListener;
51
 	private final ListenerHandle<LiveInt.Listener> contentsHeightListener;
54
 	private final ListenerHandle<LiveInt.Listener> offsetXListener;
52
 	private final ListenerHandle<LiveInt.Listener> offsetXListener;
55
 	private final ListenerHandle<LiveInt.Listener> offsetYListener;
53
 	private final ListenerHandle<LiveInt.Listener> offsetYListener;
56
-	private final ListenerHandle<LiveInt.Listener> preferredHeightListener;
57
 	private final ListenerHandle<LiveObject.Listener<DSizing>> contentsSizingListener;
54
 	private final ListenerHandle<LiveObject.Listener<DSizing>> contentsSizingListener;
58
 	
55
 	
59
 	private DComponent hovering = null;
56
 	private DComponent hovering = null;
60
 	
57
 	
61
 	private DSubSurface subSurface;
58
 	private DSubSurface subSurface;
62
 	
59
 	
63
-	public DScrollPane(DStyleClass styleClass, DComponent contents, LiveInt preferredHeight) {
60
+	public DScrollPane(DStyleClass styleClass, DComponent contents, LiveObject<DSizing> sizing) {
61
+		this.sizing = sizing;
64
 		this.styleClass = styleClass;
62
 		this.styleClass = styleClass;
65
 		this.contents = contents;
63
 		this.contents = contents;
66
-		this.preferredHeight = preferredHeight;
67
 		
64
 		
68
 		contentsHeight = new SimpleLiveInt(0);
65
 		contentsHeight = new SimpleLiveInt(0);
69
 		offsetX = new SimpleLiveInt(0);
66
 		offsetX = new SimpleLiveInt(0);
75
 		offsetXListener = offsetX.addListener(new ScrollListener());
72
 		offsetXListener = offsetX.addListener(new ScrollListener());
76
 		offsetYListener = offsetY.addListener(new ScrollListener());
73
 		offsetYListener = offsetY.addListener(new ScrollListener());
77
 		
74
 		
78
-		contents.getSizing().addListener((oldPreferences, newPreferences) -> {
75
+		contentsSizingListener = contents.getSizing().addListener((oldPreferences, newPreferences) -> {
79
 			if (bounds == null)
76
 			if (bounds == null)
80
 				return;
77
 				return;
81
 			
78
 			
82
 			contents.setBounds(new DIRectangle(0, 0, bounds.width, Math.max(bounds.height, newPreferences.preferredHeight)));
79
 			contents.setBounds(new DIRectangle(0, 0, bounds.width, Math.max(bounds.height, newPreferences.preferredHeight)));
83
 			contentsHeight.setValue(newPreferences.preferredHeight);
80
 			contentsHeight.setValue(newPreferences.preferredHeight);
84
 		});
81
 		});
85
-		preferredHeightListener = preferredHeight.addListener((oldValue, newValue) -> {
86
-			sizing.setValue(new DSizing(contents.getSizing().getValue().preferredWidth, newValue));
87
-		});
88
-		contentsSizingListener = contents.getSizing().addListener((oldValue, newValue) -> {
89
-			sizing.setValue(new DSizing(newValue.preferredWidth, preferredHeight.getValue()));
90
-		});
91
 	}
82
 	}
92
 	
83
 	
93
 	@Override
84
 	@Override
103
 	@Override
94
 	@Override
104
 	public void mount(DStylePath parent, int z, DDrawSurface surface) {
95
 	public void mount(DStylePath parent, int z, DDrawSurface surface) {
105
 		this.surface = surface;
96
 		this.surface = surface;
97
+		this.z = z;
106
 		
98
 		
107
 		DStylePath path = parent.getChild("scrollpane", styleClass);
99
 		DStylePath path = parent.getChild("scrollpane", styleClass);
108
 		subSurface = surface.createSubSurface(z + 1);
100
 		subSurface = surface.createSubSurface(z + 1);
109
-		contents.mount(path, 0, subSurface);
101
+		contents.mount(path, 1, subSurface);
110
 		scrollBar.mount(path, z + 2, surface);
102
 		scrollBar.mount(path, z + 2, surface);
111
 		style = new DScrollPaneStyle(surface.getStylesheet(path));
103
 		style = new DScrollPaneStyle(surface.getStylesheet(path));
112
 	}
104
 	}
143
 		shape = surface.shadowPath(z, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
135
 		shape = surface.shadowPath(z, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
144
 		style.border.update(surface, z + 1, style.margin.apply(bounds));
136
 		style.border.update(surface, z + 1, style.margin.apply(bounds));
145
 		
137
 		
146
-		int height = Math.max(bounds.height - style.border.getPaddingTop() - style.border.getPaddingBottom(),
138
+		int height = Math.max(
139
+				bounds.height - style.border.getPaddingHorizontal(),
147
 				contents.getSizing().getValue().preferredHeight);
140
 				contents.getSizing().getValue().preferredHeight);
148
 		int scrollBarWidth = scrollBar.getSizing().getValue().preferredWidth;
141
 		int scrollBarWidth = scrollBar.getSizing().getValue().preferredWidth;
149
 		scrollBar.setBounds(new DIRectangle(
142
 		scrollBar.setBounds(new DIRectangle(
156
 		
149
 		
157
 		subSurface.setOffset(bounds.x - offsetX.getValue(), bounds.y - offsetY.getValue());
150
 		subSurface.setOffset(bounds.x - offsetX.getValue(), bounds.y - offsetY.getValue());
158
 		subSurface.setClip(new DIRectangle(
151
 		subSurface.setClip(new DIRectangle(
159
-				bounds.x + style.border.getPaddingLeft(),
160
-				bounds.y + style.border.getPaddingTop(),
161
-				bounds.width - style.border.getPaddingLeft() - style.border.getPaddingTop(),
162
-				bounds.height - style.border.getPaddingTop() - style.border.getPaddingBottom()));
152
+				bounds.x + style.margin.left + style.border.getPaddingLeft(),
153
+				bounds.y + style.margin.top + style.border.getPaddingTop(),
154
+				bounds.width - style.margin.getHorizontal() - style.border.getPaddingHorizontal(),
155
+				bounds.height - style.margin.getVertical() - style.border.getPaddingVertical()));
163
 	}
156
 	}
164
 	
157
 	
165
 	@Override
158
 	@Override
228
 	public void close() {
221
 	public void close() {
229
 		contents.close();
222
 		contents.close();
230
 		unmount();
223
 		unmount();
224
+		
225
+		contentsSizingListener.close();
226
+		contentsHeightListener.close();
227
+		offsetXListener.close();
228
+		offsetYListener.close();
231
 	}
229
 	}
232
 	
230
 	
233
 	private DMouseEvent forward(DComponent target, DMouseEvent e) {
231
 	private DMouseEvent forward(DComponent target, DMouseEvent e) {
271
 		return y - bounds.y + offsetY.getValue();
269
 		return y - bounds.y + offsetY.getValue();
272
 	}
270
 	}
273
 	
271
 	
274
-	private class TranslatedContext implements DUIContext {
275
-		private final DUIContext context;
276
-		
277
-		public TranslatedContext(DUIContext context) {
278
-			this.context = context;
279
-		}
280
-		
281
-		@Override
282
-		public DStyleSheets getStylesheets(){
283
-			return context.getStylesheets();
284
-		}
285
-
286
-		@Override
287
-		public float getScale() {
288
-			return context.getScale();
289
-		}
290
-		
291
-		@Override
292
-		public float getTextScale() {
293
-			return context.getTextScale();
294
-		}
295
-
296
-		@Override
297
-		public void repaint(int x, int y, int width, int height) {
298
-			int left = toGlobalX(x);
299
-			int top = toGlobalY(y);
300
-			int right = left + width;
301
-			int bottom = top + height;
302
-			
303
-			left = Math.max(bounds.x, left);
304
-			top = Math.max(bounds.y, top);
305
-			right = Math.min(bounds.x + bounds.width, right);
306
-			bottom = Math.min(bounds.y + bounds.height, bottom);
307
-			
308
-			if (left >= right || top >= bottom)
309
-				return;
310
-			
311
-			context.repaint(left, top, right - left, bottom - top);
312
-		}
313
-
314
-		@Override
315
-		public void setCursor(Cursor cursor) {
316
-			context.setCursor(cursor);
317
-		}
318
-
319
-		@Override
320
-		public DFontMetrics getFontMetrics(DFont font) {
321
-			return context.getFontMetrics(font);
322
-		}
323
-
324
-		@Override
325
-		public void scrollInView(int x, int y, int width, int height) {
326
-			if (y < offsetY.getValue())
327
-				offsetY.setValue(y);
328
-			if (y + height > offsetY.getValue() + bounds.height)
329
-				offsetY.setValue(y + height - bounds.height);
330
-		}
331
-
332
-		@Override
333
-		public DTimerHandle setTimer(int millis, Runnable target) {
334
-			return context.setTimer(millis, target);
335
-		}
336
-
337
-		@Override
338
-		public DClipboard getClipboard() {
339
-			return context.getClipboard();
340
-		}
341
-
342
-		@Override
343
-		public DUIWindow getWindow() {
344
-			return context.getWindow();
345
-		}
346
-
347
-		@Override
348
-		public DUIWindow openDialog(int x, int y, DAnchor anchor, String title, DComponent root) {
349
-			return context.openDialog(toGlobalX(x), toGlobalY(y), anchor, title, root);
350
-		}
351
-
352
-		@Override
353
-		public DUIWindow openView(int x, int y, DAnchor anchor, DComponent root) {
354
-			return context.openView(toGlobalX(x), toGlobalY(y), anchor, root);
355
-		}
356
-	}
357
-	
358
 	private class ScrollListener implements LiveInt.Listener {
272
 	private class ScrollListener implements LiveInt.Listener {
359
 
273
 
360
 		@Override
274
 		@Override

+ 4
- 3
DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingSubSurface.java View File

46
 		
46
 		
47
 		AffineTransform oldTransform = g.getTransform();
47
 		AffineTransform oldTransform = g.getTransform();
48
 		g.transform(AffineTransform.getTranslateInstance(surface.offsetX, surface.offsetY));
48
 		g.transform(AffineTransform.getTranslateInstance(surface.offsetX, surface.offsetY));
49
-		DIRectangle newClip = this.clip == null ? clip : clip.offset(-surface.offsetX, -surface.offsetY).intersect(this.clip.offset(-surface.offsetX, -surface.offsetY));
50
-		surface.paint(g, newClip);
49
+		
50
+		DIRectangle intersection = this.clip == null ? clip : this.clip.intersect(clip);
51
+		surface.paint(g, intersection.offset(-surface.offsetX, -surface.offsetY));
51
 		g.setTransform(oldTransform);
52
 		g.setTransform(oldTransform);
52
 		g.setClip(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
53
 		g.setClip(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
53
 	}
54
 	}
75
 	
76
 	
76
 	@Override
77
 	@Override
77
 	public DIRectangle getBounds() {
78
 	public DIRectangle getBounds() {
78
-		return surface.calculateBounds();
79
+		return clip == null ? surface.calculateBounds().offset(surface.offsetX, surface.offsetY) : clip;
79
 	}
80
 	}
80
 
81
 
81
 	@Override
82
 	@Override

+ 4
- 3
DrawableGui/src/main/java/org/openzen/drawablegui/tree/DTreeView.java View File

5
  */
5
  */
6
 package org.openzen.drawablegui.tree;
6
 package org.openzen.drawablegui.tree;
7
 
7
 
8
-import java.io.Closeable;
9
 import java.util.ArrayList;
8
 import java.util.ArrayList;
10
 import java.util.List;
9
 import java.util.List;
11
 import org.openzen.drawablegui.DColorableIconInstance;
10
 import org.openzen.drawablegui.DColorableIconInstance;
17
 import org.openzen.drawablegui.DTransform2D;
16
 import org.openzen.drawablegui.DTransform2D;
18
 import org.openzen.drawablegui.DIRectangle;
17
 import org.openzen.drawablegui.DIRectangle;
19
 import org.openzen.drawablegui.DDrawableInstance;
18
 import org.openzen.drawablegui.DDrawableInstance;
19
+import org.openzen.drawablegui.Destructible;
20
 import org.openzen.drawablegui.listeners.ListenerHandle;
20
 import org.openzen.drawablegui.listeners.ListenerHandle;
21
 import org.openzen.drawablegui.live.LiveBool;
21
 import org.openzen.drawablegui.live.LiveBool;
22
 import org.openzen.drawablegui.draw.DDrawSurface;
22
 import org.openzen.drawablegui.draw.DDrawSurface;
23
 import org.openzen.drawablegui.draw.DDrawnRectangle;
23
 import org.openzen.drawablegui.draw.DDrawnRectangle;
24
 import org.openzen.drawablegui.draw.DDrawnText;
24
 import org.openzen.drawablegui.draw.DDrawnText;
25
 import org.openzen.drawablegui.live.LiveList;
25
 import org.openzen.drawablegui.live.LiveList;
26
+import org.openzen.drawablegui.live.LiveObject;
26
 import org.openzen.drawablegui.live.MutableLiveObject;
27
 import org.openzen.drawablegui.live.MutableLiveObject;
27
 import org.openzen.drawablegui.style.DStyleClass;
28
 import org.openzen.drawablegui.style.DStyleClass;
28
 import org.openzen.drawablegui.style.DStylePath;
29
 import org.openzen.drawablegui.style.DStylePath;
94
 	}
95
 	}
95
 
96
 
96
 	@Override
97
 	@Override
97
-	public MutableLiveObject<DSizing> getSizing() {
98
+	public LiveObject<DSizing> getSizing() {
98
 		return sizing;
99
 		return sizing;
99
 	}
100
 	}
100
 	
101
 	
233
 		// nothing to clean up
234
 		// nothing to clean up
234
 	}
235
 	}
235
 	
236
 	
236
-	private class Row implements Closeable, LiveBool.Listener, LiveList.Listener<N> {
237
+	private class Row implements Destructible, LiveBool.Listener, LiveList.Listener<N> {
237
 		private final int x;
238
 		private final int x;
238
 		private final int index;
239
 		private final int index;
239
 		private final N node;
240
 		private final N node;

+ 1
- 4
IDE/src/main/java/org/openzen/zenscript/ide/Main.java View File

24
 		Arguments arguments = new Arguments(args);
24
 		Arguments arguments = new Arguments(args);
25
 		File directory = arguments.projectDirectory;
25
 		File directory = arguments.projectDirectory;
26
 		
26
 		
27
-		CompilationUnit compilationUnit = new CompilationUnit();
28
-		ModuleLoader loader = new ModuleLoader(compilationUnit);
29
-		Project project = new Project(loader, directory);
30
-		
27
+		Project project = new Project(directory);
31
 		DevelopmentHost host = new LocalProjectDevelopmentHost(project);
28
 		DevelopmentHost host = new LocalProjectDevelopmentHost(project);
32
 		open(host);
29
 		open(host);
33
     }
30
     }

+ 5
- 2
IDE/src/main/java/org/openzen/zenscript/ide/host/IDETarget.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.ide.host;
6
 package org.openzen.zenscript.ide.host;
7
 
7
 
8
+import java.util.function.Consumer;
9
+import org.openzen.zenscript.ide.ui.view.output.OutputLine;
10
+
8
 /**
11
 /**
9
  *
12
  *
10
  * @author Hoofdgebruiker
13
  * @author Hoofdgebruiker
16
 	
19
 	
17
 	boolean canRun();
20
 	boolean canRun();
18
 	
21
 	
19
-	void build();
22
+	void build(Consumer<OutputLine> output);
20
 	
23
 	
21
-	void run();
24
+	void run(Consumer<OutputLine> output);
22
 }
25
 }

+ 39
- 17
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java View File

6
 package org.openzen.zenscript.ide.host.local;
6
 package org.openzen.zenscript.ide.host.local;
7
 
7
 
8
 import java.io.File;
8
 import java.io.File;
9
-import java.io.IOException;
10
 import java.util.HashSet;
9
 import java.util.HashSet;
11
 import java.util.Set;
10
 import java.util.Set;
11
+import java.util.function.Consumer;
12
 import org.openzen.zenscript.compiler.Target;
12
 import org.openzen.zenscript.compiler.Target;
13
 import org.openzen.zenscript.compiler.ZenCodeCompiler;
13
 import org.openzen.zenscript.compiler.ZenCodeCompiler;
14
 import org.openzen.zenscript.constructor.Library;
14
 import org.openzen.zenscript.constructor.Library;
15
 import org.openzen.zenscript.constructor.ModuleLoader;
15
 import org.openzen.zenscript.constructor.ModuleLoader;
16
 import org.openzen.zenscript.constructor.Project;
16
 import org.openzen.zenscript.constructor.Project;
17
-import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
17
+import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
18
 import org.openzen.zenscript.constructor.module.ModuleReference;
18
 import org.openzen.zenscript.constructor.module.ModuleReference;
19
 import org.openzen.zenscript.compiler.SemanticModule;
19
 import org.openzen.zenscript.compiler.SemanticModule;
20
 import org.openzen.zenscript.compiler.CompilationUnit;
20
 import org.openzen.zenscript.compiler.CompilationUnit;
21
 import org.openzen.zenscript.ide.host.IDETarget;
21
 import org.openzen.zenscript.ide.host.IDETarget;
22
+import org.openzen.zenscript.ide.ui.view.output.ErrorOutputSpan;
23
+import org.openzen.zenscript.ide.ui.view.output.OutputLine;
24
+import org.openzen.zenscript.validator.ValidationLogEntry;
25
+import stdlib.Strings;
22
 
26
 
23
 /**
27
 /**
24
  *
28
  *
49
 	}
53
 	}
50
 
54
 
51
 	@Override
55
 	@Override
52
-	public void build() {
53
-		buildInternal();
56
+	public void build(Consumer<OutputLine> output) {
57
+		buildInternal(output);
54
 	}
58
 	}
55
 
59
 
56
 	@Override
60
 	@Override
57
-	public void run() {
58
-		ZenCodeCompiler compiler = buildInternal();
61
+	public void run(Consumer<OutputLine> output) {
62
+		ZenCodeCompiler compiler = buildInternal(output);
59
 		if (compiler != null)
63
 		if (compiler != null)
60
 			compiler.run();
64
 			compiler.run();
61
 	}
65
 	}
62
 	
66
 	
63
-	private ZenCodeCompiler buildInternal() {
67
+	private ZenCodeCompiler buildInternal(Consumer<OutputLine> output) {
64
 		CompilationUnit compilationUnit = new CompilationUnit();
68
 		CompilationUnit compilationUnit = new CompilationUnit();
65
-		ModuleLoader moduleLoader = new ModuleLoader(compilationUnit);
66
-		moduleLoader.register("stdlib", new DirectoryModuleLoader(moduleLoader, "stdlib", new File("../../StdLibs/stdlib"), true));
69
+		ModuleLoader moduleLoader = new ModuleLoader(compilationUnit, exception -> output.accept(new OutputLine(new ErrorOutputSpan(exception.getMessage()))));
70
+		moduleLoader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
67
 		Set<String> compiledModules = new HashSet<>();
71
 		Set<String> compiledModules = new HashSet<>();
68
 		
72
 		
73
+		Consumer<ValidationLogEntry> validationLogger = entry -> {
74
+			String[] message = Strings.split(entry.message, '\n');
75
+			output.accept(new OutputLine(new ErrorOutputSpan(entry.kind + " " + entry.position.toString() + ": " + message[0])));
76
+			for (int i = 1; i < message.length; i++)
77
+				output.accept(new OutputLine(new ErrorOutputSpan("    " + message[i])));
78
+		};
69
 		try {
79
 		try {
70
-			Project project = new Project(moduleLoader, this.project.directory);
71
 			for (Library library : project.libraries) {
80
 			for (Library library : project.libraries) {
72
 				for (ModuleReference module : library.modules)
81
 				for (ModuleReference module : library.modules)
73
 					moduleLoader.register(module.getName(), module);
82
 					moduleLoader.register(module.getName(), module);
78
 			
87
 			
79
 			SemanticModule module = moduleLoader.getModule(target.getModule());
88
 			SemanticModule module = moduleLoader.getModule(target.getModule());
80
 			module = module.normalize();
89
 			module = module.normalize();
81
-			module.validate();
90
+			module.validate(validationLogger);
82
 			
91
 			
83
 			ZenCodeCompiler compiler = target.createCompiler(module);
92
 			ZenCodeCompiler compiler = target.createCompiler(module);
84
 			if (!module.isValid())
93
 			if (!module.isValid())
86
 			
95
 			
87
 			SemanticModule stdlib = moduleLoader.getModule("stdlib");
96
 			SemanticModule stdlib = moduleLoader.getModule("stdlib");
88
 			stdlib = stdlib.normalize();
97
 			stdlib = stdlib.normalize();
89
-			stdlib.validate();
98
+			stdlib.validate(validationLogger);
90
 			if (!stdlib.isValid())
99
 			if (!stdlib.isValid())
91
 				return compiler;
100
 				return compiler;
92
 			stdlib.compile(compiler);
101
 			stdlib.compile(compiler);
93
 			compiledModules.add(stdlib.name);
102
 			compiledModules.add(stdlib.name);
94
 			
103
 			
95
-			boolean isValid = compileDependencies(moduleLoader, compiler, compiledModules, module);
104
+			boolean isValid = compileDependencies(moduleLoader, compiler, compiledModules, module, validationLogger);
96
 			if (!isValid)
105
 			if (!isValid)
97
 				return compiler;
106
 				return compiler;
98
 			
107
 			
99
 			module.compile(compiler);
108
 			module.compile(compiler);
100
 			compiler.finish();
109
 			compiler.finish();
101
 			return compiler;
110
 			return compiler;
102
-		} catch (IOException ex) {
111
+		} catch (Exception ex) {
103
 			ex.printStackTrace();
112
 			ex.printStackTrace();
113
+			
114
+			for (String line : Strings.split(ex.toString(), '\n'))
115
+				output.accept(new OutputLine(new ErrorOutputSpan(line)));
116
+			for (StackTraceElement element : ex.getStackTrace()) {
117
+				String source;
118
+				if (element.isNativeMethod()) {
119
+					source = "(Native Method)";
120
+				} else {
121
+					source = "(" + element.getFileName() + ":" + element.getLineNumber() + ")";
122
+				}
123
+				output.accept(new OutputLine(new ErrorOutputSpan("    at " + element.getClassName() + "." + element.getMethodName() + source)));
124
+			}
125
+			
104
 			return null;
126
 			return null;
105
 		}
127
 		}
106
 	}
128
 	}
107
 	
129
 	
108
-	private boolean compileDependencies(ModuleLoader loader, ZenCodeCompiler compiler, Set<String> compiledModules, SemanticModule module) {
130
+	private boolean compileDependencies(ModuleLoader loader, ZenCodeCompiler compiler, Set<String> compiledModules, SemanticModule module, Consumer<ValidationLogEntry> logger) {
109
 		for (String dependency : module.dependencies) {
131
 		for (String dependency : module.dependencies) {
110
 			if (compiledModules.contains(module.name))
132
 			if (compiledModules.contains(module.name))
111
 				continue;
133
 				continue;
112
 			
134
 			
113
 			SemanticModule dependencyModule = loader.getModule(dependency);
135
 			SemanticModule dependencyModule = loader.getModule(dependency);
114
 			module = module.normalize();
136
 			module = module.normalize();
115
-			module.validate();
137
+			module.validate(logger);
116
 			if (!module.isValid())
138
 			if (!module.isValid())
117
 				return false;
139
 				return false;
118
 			
140
 			
119
-			if (!compileDependencies(loader, compiler, compiledModules, dependencyModule))
141
+			if (!compileDependencies(loader, compiler, compiledModules, dependencyModule, logger))
120
 				return false;
142
 				return false;
121
 			
143
 			
122
 			module.compile(compiler);
144
 			module.compile(compiler);

+ 21
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEStyling.java View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui;
7
+
8
+import org.openzen.drawablegui.style.DRoundedRectangleShape;
9
+import org.openzen.drawablegui.style.DShadow;
10
+import org.openzen.drawablegui.style.DShadowElement;
11
+import org.openzen.drawablegui.style.DShapeElement;
12
+
13
+/**
14
+ *
15
+ * @author Hoofdgebruiker
16
+ */
17
+public class IDEStyling {
18
+	public static final DShadowElement BLOCK_SHADOW = context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale());
19
+	public static final DShapeElement BLOCK_SHAPE = context -> new DRoundedRectangleShape(context.dp(2));
20
+	public static final int ERROR_RED = 0xFFE81123;
21
+}

+ 6
- 2
IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEWindow.java View File

6
 package org.openzen.zenscript.ide.ui;
6
 package org.openzen.zenscript.ide.ui;
7
 
7
 
8
 import org.openzen.drawablegui.live.ImmutableLiveString;
8
 import org.openzen.drawablegui.live.ImmutableLiveString;
9
+import org.openzen.drawablegui.live.LiveArrayList;
10
+import org.openzen.drawablegui.live.MutableLiveList;
9
 import org.openzen.drawablegui.style.DStyleClass;
11
 import org.openzen.drawablegui.style.DStyleClass;
10
 import org.openzen.zenscript.ide.host.DevelopmentHost;
12
 import org.openzen.zenscript.ide.host.DevelopmentHost;
11
 import org.openzen.zenscript.ide.host.IDESourceFile;
13
 import org.openzen.zenscript.ide.host.IDESourceFile;
15
 import org.openzen.zenscript.ide.ui.icons.SettingsIcon;
17
 import org.openzen.zenscript.ide.ui.icons.SettingsIcon;
16
 import org.openzen.zenscript.ide.ui.icons.ShadedProjectIcon;
18
 import org.openzen.zenscript.ide.ui.icons.ShadedProjectIcon;
17
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
19
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
20
+import org.openzen.zenscript.ide.ui.view.output.OutputLine;
18
 
21
 
19
 /**
22
 /**
20
  *
23
  *
26
 	public final IDEAspectBar aspectBar;
29
 	public final IDEAspectBar aspectBar;
27
 	public final IDEDockWindow dockWindow;
30
 	public final IDEDockWindow dockWindow;
28
 	public final IDEStatusBar statusBar;
31
 	public final IDEStatusBar statusBar;
32
+	public final MutableLiveList<OutputLine> output = new LiveArrayList<>();
29
 	
33
 	
30
 	public IDEAspectToolbar projectToolbar;
34
 	public IDEAspectToolbar projectToolbar;
31
 	
35
 	
59
 		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, BuildIcon.BLUE, new ImmutableLiveString("Build"), e -> {
63
 		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, BuildIcon.BLUE, new ImmutableLiveString("Build"), e -> {
60
 			for (IDETarget target : host.getTargets()) {
64
 			for (IDETarget target : host.getTargets()) {
61
 				if (target.canBuild())
65
 				if (target.canBuild())
62
-					target.build();
66
+					target.build(line -> output.add(line));
63
 			}
67
 			}
64
 		}));
68
 		}));
65
 		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, PlayIcon.GREEN, new ImmutableLiveString("Run"), e -> {
69
 		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, PlayIcon.GREEN, new ImmutableLiveString("Run"), e -> {
66
 			for (IDETarget target : host.getTargets()) {
70
 			for (IDETarget target : host.getTargets()) {
67
 				if (target.canRun())
71
 				if (target.canRun())
68
-					target.run();
72
+					target.run(line -> output.add(line));
69
 			}
73
 			}
70
 		}));
74
 		}));
71
 		aspectBar.toolbars.add(projectToolbar);
75
 		aspectBar.toolbars.add(projectToolbar);

+ 0
- 3
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabClose.java View File

96
 		drawnIcon = new DColorableIconInstance(surface, z + 1, icon, DTransform2D.translate(
96
 		drawnIcon = new DColorableIconInstance(surface, z + 1, icon, DTransform2D.translate(
97
 				bounds.x + (bounds.width - icon.getNominalWidth()) / 2,
97
 				bounds.x + (bounds.width - icon.getNominalWidth()) / 2,
98
 				bounds.y + (bounds.height - icon.getNominalHeight()) / 2), 0xFF000000);
98
 				bounds.y + (bounds.height - icon.getNominalHeight()) / 2), 0xFF000000);
99
-		/*drawnIcon.setTransform(DTransform2D.translate(
100
-				bounds.x + (bounds.width - icon.getNominalWidth()) / 2,
101
-				bounds.y + (bounds.height - icon.getNominalHeight()) / 2));*/
102
 	}
99
 	}
103
 
100
 
104
 	@Override
101
 	@Override

+ 17
- 1
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/WindowView.java View File

6
 package org.openzen.zenscript.ide.ui.view;
6
 package org.openzen.zenscript.ide.ui.view;
7
 
7
 
8
 import org.openzen.drawablegui.DEmptyView;
8
 import org.openzen.drawablegui.DEmptyView;
9
+import org.openzen.drawablegui.DSizing;
9
 import org.openzen.drawablegui.border.DLineBorder;
10
 import org.openzen.drawablegui.border.DLineBorder;
10
 import org.openzen.drawablegui.scroll.DScrollPane;
11
 import org.openzen.drawablegui.scroll.DScrollPane;
11
 import org.openzen.drawablegui.layout.DSideLayout;
12
 import org.openzen.drawablegui.layout.DSideLayout;
13
+import org.openzen.drawablegui.live.LiveArrayList;
12
 import org.openzen.drawablegui.live.LiveString;
14
 import org.openzen.drawablegui.live.LiveString;
15
+import org.openzen.drawablegui.live.MutableLiveList;
13
 import org.openzen.drawablegui.live.SimpleLiveInt;
16
 import org.openzen.drawablegui.live.SimpleLiveInt;
17
+import org.openzen.drawablegui.live.SimpleLiveObject;
14
 import org.openzen.drawablegui.live.SimpleLiveString;
18
 import org.openzen.drawablegui.live.SimpleLiveString;
15
 import org.openzen.drawablegui.style.DShadow;
19
 import org.openzen.drawablegui.style.DShadow;
16
 import org.openzen.drawablegui.style.DStyleClass;
20
 import org.openzen.drawablegui.style.DStyleClass;
21
 import org.openzen.zenscript.ide.ui.IDEWindow;
25
 import org.openzen.zenscript.ide.ui.IDEWindow;
22
 import org.openzen.zenscript.ide.ui.view.aspectbar.AspectBarView;
26
 import org.openzen.zenscript.ide.ui.view.aspectbar.AspectBarView;
23
 import org.openzen.zenscript.ide.ui.view.editor.SourceEditor;
27
 import org.openzen.zenscript.ide.ui.view.editor.SourceEditor;
28
+import org.openzen.zenscript.ide.ui.view.output.OutputLine;
29
+import org.openzen.zenscript.ide.ui.view.output.OutputView;
24
 import org.openzen.zenscript.ide.ui.view.project.ProjectBrowser;
30
 import org.openzen.zenscript.ide.ui.view.project.ProjectBrowser;
25
 
31
 
26
 /**
32
 /**
41
 		
47
 		
42
 		projectBrowser = new ProjectBrowser(window, host);
48
 		projectBrowser = new ProjectBrowser(window, host);
43
 		
49
 		
50
+		OutputView output = new OutputView(DStyleClass.EMPTY, window.output);
51
+		
52
+		DScrollPane scrollOutput = new DScrollPane(DStyleClass.inline(new DStylesheetBuilder()
53
+							//.border("border", context -> new DLineBorder(0xFF888888, 1))
54
+							.marginDp("margin", 3)
55
+							.color("backgroundColor", 0xFFFFFFFF)
56
+							.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
57
+							.build()), output, new SimpleLiveObject<>(new DSizing(400, 400)));
58
+		
44
 		setMain(tabs = new TabbedView(DStyleClass.inline(new DStylesheetBuilder()
59
 		setMain(tabs = new TabbedView(DStyleClass.inline(new DStylesheetBuilder()
45
 				.marginDp("margin", 3)
60
 				.marginDp("margin", 3)
46
 				.build())));
61
 				.build())));
62
+		add(Side.BOTTOM, scrollOutput);
47
 		add(Side.LEFT, projectBrowser.view);
63
 		add(Side.LEFT, projectBrowser.view);
48
 		add(Side.BOTTOM, new StatusBarView(DStyleClass.EMPTY, status));
64
 		add(Side.BOTTOM, new StatusBarView(DStyleClass.EMPTY, status));
49
 		add(Side.TOP, new AspectBarView(DStyleClass.EMPTY, window.aspectBar));
65
 		add(Side.TOP, new AspectBarView(DStyleClass.EMPTY, window.aspectBar));
61
 					new DScrollPane(DStyleClass.inline(new DStylesheetBuilder()
77
 					new DScrollPane(DStyleClass.inline(new DStylesheetBuilder()
62
 							.border("border", context -> new DLineBorder(0xFF888888, 1))
78
 							.border("border", context -> new DLineBorder(0xFF888888, 1))
63
 							//.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
79
 							//.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
64
-							.build()), editor, new SimpleLiveInt(0)),
80
+							.build()), editor, new SimpleLiveObject<>(new DSizing(500, 500))),
65
 					editor.isUpdated());
81
 					editor.isUpdated());
66
 			tabs.tabs.add(tab);
82
 			tabs.tabs.add(tab);
67
 			tabs.currentTab.setValue(tab);
83
 			tabs.currentTab.setValue(tab);

+ 10
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/BasicOutputSpan.java View File

20
 	public String toString() {
20
 	public String toString() {
21
 		return value;
21
 		return value;
22
 	}
22
 	}
23
+
24
+	@Override
25
+	public String getText() {
26
+		return value;
27
+	}
28
+
29
+	@Override
30
+	public int getColor() {
31
+		return 0xFF000000;
32
+	}
23
 }
33
 }

+ 12
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/ErrorOutputSpan.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.ide.ui.view.output;
6
 package org.openzen.zenscript.ide.ui.view.output;
7
 
7
 
8
+import org.openzen.zenscript.ide.ui.IDEStyling;
9
+
8
 /**
10
 /**
9
  *
11
  *
10
  * @author Hoofdgebruiker
12
  * @author Hoofdgebruiker
20
 	public String toString() {
22
 	public String toString() {
21
 		return value;
23
 		return value;
22
 	}
24
 	}
25
+
26
+	@Override
27
+	public String getText() {
28
+		return value;
29
+	}
30
+
31
+	@Override
32
+	public int getColor() {
33
+		return IDEStyling.ERROR_RED;
34
+	}
23
 }
35
 }

+ 8
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputLine.java View File

12
 public class OutputLine {
12
 public class OutputLine {
13
 	public final OutputSpan[] spans;
13
 	public final OutputSpan[] spans;
14
 	
14
 	
15
+	public OutputLine(String line) {
16
+		spans = new OutputSpan[] { new BasicOutputSpan(line) };
17
+	}
18
+	
19
+	public OutputLine(OutputSpan span) {
20
+		spans = new OutputSpan[] { span };
21
+	}
22
+	
15
 	public OutputLine(OutputSpan[] spans) {
23
 	public OutputLine(OutputSpan[] spans) {
16
 		this.spans = spans;
24
 		this.spans = spans;
17
 	}
25
 	}

+ 2
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputSpan.java View File

10
  * @author Hoofdgebruiker
10
  * @author Hoofdgebruiker
11
  */
11
  */
12
 public interface OutputSpan {
12
 public interface OutputSpan {
13
+	public String getText();
13
 	
14
 	
15
+	public int getColor();
14
 }
16
 }

+ 81
- 2
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputView.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.ide.ui.view.output;
6
 package org.openzen.zenscript.ide.ui.view.output;
7
 
7
 
8
+import java.util.ArrayList;
9
+import java.util.List;
8
 import org.openzen.drawablegui.DComponent;
10
 import org.openzen.drawablegui.DComponent;
11
+import org.openzen.drawablegui.DFontMetrics;
9
 import org.openzen.drawablegui.DIRectangle;
12
 import org.openzen.drawablegui.DIRectangle;
10
 import org.openzen.drawablegui.DSizing;
13
 import org.openzen.drawablegui.DSizing;
11
 import org.openzen.drawablegui.DTransform2D;
14
 import org.openzen.drawablegui.DTransform2D;
15
+import org.openzen.drawablegui.Destructible;
12
 import org.openzen.drawablegui.draw.DDrawSurface;
16
 import org.openzen.drawablegui.draw.DDrawSurface;
13
 import org.openzen.drawablegui.draw.DDrawnShape;
17
 import org.openzen.drawablegui.draw.DDrawnShape;
18
+import org.openzen.drawablegui.draw.DDrawnText;
19
+import org.openzen.drawablegui.listeners.ListenerHandle;
14
 import org.openzen.drawablegui.live.LiveList;
20
 import org.openzen.drawablegui.live.LiveList;
21
+import org.openzen.drawablegui.live.LiveObject;
15
 import org.openzen.drawablegui.live.MutableLiveObject;
22
 import org.openzen.drawablegui.live.MutableLiveObject;
16
 import org.openzen.drawablegui.style.DStyleClass;
23
 import org.openzen.drawablegui.style.DStyleClass;
17
 import org.openzen.drawablegui.style.DStylePath;
24
 import org.openzen.drawablegui.style.DStylePath;
29
 	private int z;
36
 	private int z;
30
 	private DIRectangle bounds;
37
 	private DIRectangle bounds;
31
 	private OutputViewStyle style;
38
 	private OutputViewStyle style;
39
+	private DFontMetrics fontMetrics;
40
+	private ListenerHandle<LiveList.Listener<OutputLine>> linesListener;
32
 	
41
 	
33
 	private DDrawnShape shape;
42
 	private DDrawnShape shape;
43
+	private final List<List<DDrawnText>> outputText = new ArrayList<>();
34
 	
44
 	
35
 	public OutputView(DStyleClass styleClass, LiveList<OutputLine> lines) {
45
 	public OutputView(DStyleClass styleClass, LiveList<OutputLine> lines) {
36
 		this.styleClass = styleClass;
46
 		this.styleClass = styleClass;
39
 
49
 
40
 	@Override
50
 	@Override
41
 	public void mount(DStylePath parent, int z, DDrawSurface surface) {
51
 	public void mount(DStylePath parent, int z, DDrawSurface surface) {
52
+		if (this.surface != null)
53
+			unmount();
54
+		
42
 		this.surface = surface;
55
 		this.surface = surface;
43
 		this.z = z;
56
 		this.z = z;
44
 		
57
 		
45
 		DStylePath path = parent.getChild("outputview", styleClass);
58
 		DStylePath path = parent.getChild("outputview", styleClass);
46
 		style = new OutputViewStyle(surface.getStylesheet(path));
59
 		style = new OutputViewStyle(surface.getStylesheet(path));
60
+		fontMetrics = surface.getFontMetrics(style.font);
61
+		
62
+		for (OutputLine line : lines)
63
+			outputText.add(draw(line));
64
+		
65
+		linesListener = lines.addListener(new LinesListener());
66
+		updateSizing();
47
 	}
67
 	}
48
 	
68
 	
49
 	@Override
69
 	@Override
50
 	public void unmount() {
70
 	public void unmount() {
71
+		surface = null;
72
+		
51
 		if (shape != null) {
73
 		if (shape != null) {
52
 			shape.close();
74
 			shape.close();
53
 			shape = null;
75
 			shape = null;
54
 		}
76
 		}
77
+		
78
+		for (List<DDrawnText> line : outputText)
79
+			Destructible.close(line);
80
+		
81
+		outputText.clear();
82
+		linesListener.close();
55
 	}
83
 	}
56
 
84
 
57
 	@Override
85
 	@Override
58
-	public MutableLiveObject<DSizing> getSizing() {
86
+	public LiveObject<DSizing> getSizing() {
59
 		return sizing;
87
 		return sizing;
60
 	}
88
 	}
61
 
89
 
72
 	@Override
100
 	@Override
73
 	public void setBounds(DIRectangle bounds) {
101
 	public void setBounds(DIRectangle bounds) {
74
 		this.bounds = bounds;
102
 		this.bounds = bounds;
75
-		shape = surface.shadowPath(z, style.shape.instance(bounds), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
103
+		
104
+		DIRectangle available = style.margin.apply(bounds);
105
+		shape = surface.shadowPath(z, style.shape.instance(available), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
106
+		
107
+		layout(0);
76
 	}
108
 	}
77
 
109
 
78
 	@Override
110
 	@Override
79
 	public void close() {
111
 	public void close() {
80
 		unmount();
112
 		unmount();
81
 	}
113
 	}
114
+	
115
+	private void updateSizing() {
116
+		sizing.setValue(new DSizing(100, lines.size() * fontMetrics.getLineHeight() + style.margin.getVertical() + style.border.getPaddingVertical()));
117
+	}
118
+	
119
+	private List<DDrawnText> draw(OutputLine line) {
120
+		List<DDrawnText> lineText = new ArrayList<>();
121
+		for (OutputSpan span : line.spans)
122
+			lineText.add(surface.drawText(z + 1, style.font, span.getColor(), 0, 0, span.getText()));
123
+		return lineText;
124
+	}
125
+	
126
+	private void layout(int fromIndex) {
127
+		for (int i = fromIndex; i < outputText.size(); i++)
128
+			layout(i, outputText.get(i));
129
+	}
130
+	
131
+	private void layout(int index, List<DDrawnText> line) {
132
+		int x = bounds.x + style.margin.left + style.border.getPaddingTop();
133
+		int y = bounds.y + style.margin.top + style.border.getPaddingTop() + index * fontMetrics.getLineHeight() + fontMetrics.getAscent();
134
+		for (DDrawnText text : line) {
135
+			text.setPosition(x, y);
136
+			x += text.getBounds().width;
137
+		}
138
+	}
139
+	
140
+	private class LinesListener implements LiveList.Listener<OutputLine> {
141
+		@Override
142
+		public void onInserted(int index, OutputLine value) {
143
+			outputText.add(index, draw(value));
144
+			layout(index);
145
+			updateSizing();
146
+		}
147
+
148
+		@Override
149
+		public void onChanged(int index, OutputLine oldValue, OutputLine newValue) {
150
+			List<DDrawnText> line = draw(newValue);
151
+			layout(index, line);
152
+			Destructible.close(outputText.set(index, line));
153
+		}
154
+
155
+		@Override
156
+		public void onRemoved(int index, OutputLine oldValue) {
157
+			Destructible.close(outputText.remove(index));
158
+			updateSizing();
159
+		}
160
+	}
82
 }
161
 }

+ 4
- 13
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputViewStyle.java View File

7
 
7
 
8
 import org.openzen.drawablegui.DFont;
8
 import org.openzen.drawablegui.DFont;
9
 import org.openzen.drawablegui.DFontFamily;
9
 import org.openzen.drawablegui.DFontFamily;
10
-import org.openzen.drawablegui.border.DBorder;
11
 import org.openzen.drawablegui.border.DPaddedBorder;
10
 import org.openzen.drawablegui.border.DPaddedBorder;
12
-import org.openzen.drawablegui.style.DRoundedRectangleShape;
13
-import org.openzen.drawablegui.style.DShadow;
14
-import org.openzen.drawablegui.style.DShape;
11
+import org.openzen.drawablegui.style.DBaseStyle;
15
 import org.openzen.drawablegui.style.DStyleDefinition;
12
 import org.openzen.drawablegui.style.DStyleDefinition;
16
 
13
 
17
 /**
14
 /**
18
  *
15
  *
19
  * @author Hoofdgebruiker
16
  * @author Hoofdgebruiker
20
  */
17
  */
21
-public class OutputViewStyle {
22
-	public final int backgroundColor;
23
-	public final DBorder border;
24
-	public final DShadow shadow;
25
-	public final DShape shape;
18
+public class OutputViewStyle extends DBaseStyle {
26
 	public final DFont font;
19
 	public final DFont font;
27
 	
20
 	
28
 	public OutputViewStyle(DStyleDefinition style) {
21
 	public OutputViewStyle(DStyleDefinition style) {
29
-		backgroundColor = style.getColor("backgroundColor", 0xFFFFFFFF);
30
-		border = style.getBorder("border", context -> new DPaddedBorder(context.dp(8)));
31
-		shadow = style.getShadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()));
32
-		shape = style.getShape("shape", context -> new DRoundedRectangleShape(context.dp(2)));
22
+		super(style, context -> new DPaddedBorder(context.dp(8)), 0);
23
+		
33
 		font = style.getFont("font", context -> new DFont(DFontFamily.CODE, false, false, false, context.sp(14)));
24
 		font = style.getFont("font", context -> new DFont(DFontFamily.CODE, false, false, false, context.sp(14)));
34
 	}
25
 	}
35
 }
26
 }

+ 12
- 4
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/project/ProjectBrowser.java View File

6
 package org.openzen.zenscript.ide.ui.view.project;
6
 package org.openzen.zenscript.ide.ui.view.project;
7
 
7
 
8
 import org.openzen.drawablegui.DComponent;
8
 import org.openzen.drawablegui.DComponent;
9
+import org.openzen.drawablegui.DFont;
10
+import org.openzen.drawablegui.DFontFamily;
11
+import org.openzen.drawablegui.DLabel;
9
 import org.openzen.drawablegui.DSizing;
12
 import org.openzen.drawablegui.DSizing;
10
 import org.openzen.drawablegui.border.DEmptyBorder;
13
 import org.openzen.drawablegui.border.DEmptyBorder;
11
 import org.openzen.drawablegui.border.DPaddedBorder;
14
 import org.openzen.drawablegui.border.DPaddedBorder;
18
 import org.openzen.drawablegui.live.LiveBool;
21
 import org.openzen.drawablegui.live.LiveBool;
19
 import org.openzen.drawablegui.live.LivePredicateBool;
22
 import org.openzen.drawablegui.live.LivePredicateBool;
20
 import org.openzen.drawablegui.live.MutableLiveObject;
23
 import org.openzen.drawablegui.live.MutableLiveObject;
21
-import org.openzen.drawablegui.live.SimpleLiveInt;
22
 import org.openzen.drawablegui.live.SimpleLiveObject;
24
 import org.openzen.drawablegui.live.SimpleLiveObject;
25
+import org.openzen.drawablegui.live.SimpleLiveString;
23
 import org.openzen.drawablegui.scroll.DScrollPane;
26
 import org.openzen.drawablegui.scroll.DScrollPane;
24
 import org.openzen.drawablegui.style.DRoundedRectangleShape;
27
 import org.openzen.drawablegui.style.DRoundedRectangleShape;
25
 import org.openzen.drawablegui.style.DShadow;
28
 import org.openzen.drawablegui.style.DShadow;
27
 import org.openzen.drawablegui.style.DStylesheetBuilder;
30
 import org.openzen.drawablegui.style.DStylesheetBuilder;
28
 import org.openzen.drawablegui.tree.CollapsedArrow;
31
 import org.openzen.drawablegui.tree.CollapsedArrow;
29
 import org.openzen.drawablegui.tree.DTreeView;
32
 import org.openzen.drawablegui.tree.DTreeView;
30
-import org.openzen.drawablegui.tree.DTreeViewStyle;
31
 import org.openzen.drawablegui.tree.ExpandedArrow;
33
 import org.openzen.drawablegui.tree.ExpandedArrow;
32
 import org.openzen.zenscript.ide.host.DevelopmentHost;
34
 import org.openzen.zenscript.ide.host.DevelopmentHost;
33
 import org.openzen.zenscript.ide.host.IDEModule;
35
 import org.openzen.zenscript.ide.host.IDEModule;
60
 				.dimensionDp("padding", 0)
62
 				.dimensionDp("padding", 0)
61
 				.build());
63
 				.build());
62
 		
64
 		
65
+		DLabel label = new DLabel(
66
+				DStyleClass.inline(new DStylesheetBuilder()
67
+						.font("font", context -> new DFont(DFontFamily.UI, false, false, false, context.sp(14)))
68
+						.color("color", 0xFF888888)
69
+						.build()),
70
+				new SimpleLiveString("Project Browser"));
63
 		IconButtonControl addPackageButton = new IconButtonControl(
71
 		IconButtonControl addPackageButton = new IconButtonControl(
64
 				minimalButtonPadding,
72
 				minimalButtonPadding,
65
 				AddBoxIcon.BLUE,
73
 				AddBoxIcon.BLUE,
91
 						.build()),
99
 						.build()),
92
 				Orientation.HORIZONTAL,
100
 				Orientation.HORIZONTAL,
93
 				Alignment.LEFT,
101
 				Alignment.LEFT,
102
+				new Element(label, 1, 1, ElementAlignment.CENTER),
94
 				new Element(addPackageButton, 0, 0, ElementAlignment.TOP),
103
 				new Element(addPackageButton, 0, 0, ElementAlignment.TOP),
95
 				new Element(addFileButton, 0, 0, ElementAlignment.TOP));
104
 				new Element(addFileButton, 0, 0, ElementAlignment.TOP));
96
 		DTreeView projectTree = new DTreeView(
105
 		DTreeView projectTree = new DTreeView(
98
 				ExpandedArrow.INSTANCE,
107
 				ExpandedArrow.INSTANCE,
99
 				CollapsedArrow.INSTANCE,
108
 				CollapsedArrow.INSTANCE,
100
 				new RootTreeNode(this, host), false);
109
 				new RootTreeNode(this, host), false);
101
-		projectTree.getSizing().setValue(new DSizing(500, 500));
102
 		DScrollPane treeScrollPane = new DScrollPane(
110
 		DScrollPane treeScrollPane = new DScrollPane(
103
 				DStyleClass.inline("projectView", new DStylesheetBuilder()
111
 				DStyleClass.inline("projectView", new DStylesheetBuilder()
104
 						.shape("shape", context -> new DRoundedRectangleShape(0, 0, context.dp(2), context.dp(2)))
112
 						.shape("shape", context -> new DRoundedRectangleShape(0, 0, context.dp(2), context.dp(2)))
106
 						.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
114
 						.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
107
 						.build()),
115
 						.build()),
108
 				projectTree,
116
 				projectTree,
109
-				new SimpleLiveInt(0));
117
+				new SimpleLiveObject<>(new DSizing(500, 500)));
110
 		
118
 		
111
 		view = new DLinearLayout(
119
 		view = new DLinearLayout(
112
 				DStyleClass.inline(new DStylesheetBuilder()
120
 				DStyleClass.inline(new DStylesheetBuilder()

+ 3
- 1
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java View File

142
 				Collections.emptyList());
142
 				Collections.emptyList());
143
 		
143
 		
144
 		result = result.normalize();
144
 		result = result.normalize();
145
-		result.validate();
145
+		result.validate(entry -> {
146
+			System.out.println(entry.kind + " " + entry.position.toString() + ": " + entry.message);
147
+		});
146
 		return result;
148
 		return result;
147
 	}
149
 	}
148
 	
150
 	

Loading…
Cancel
Save