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

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

@@ -8,7 +8,7 @@ package org.openzen.zenscript.constructor;
8 8
 import java.io.File;
9 9
 import org.json.JSONArray;
10 10
 import org.json.JSONObject;
11
-import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
11
+import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
12 12
 import org.openzen.zenscript.constructor.module.ModuleReference;
13 13
 
14 14
 /**
@@ -20,7 +20,7 @@ public class Library {
20 20
 	public final File directory;
21 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 24
 		this.name = name;
25 25
 		this.directory = new File(directory, json.getString("directory"));
26 26
 		
@@ -28,7 +28,7 @@ public class Library {
28 28
 		modules = new ModuleReference[modulesJson.length()];
29 29
 		for (int i = 0; i < modulesJson.length(); i++) {
30 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,9 +1,11 @@
1 1
 package org.openzen.zenscript.constructor;
2 2
 
3
-import org.openzen.zenscript.compiler.CompilationUnit;
4 3
 import java.io.File;
4
+import org.openzen.zenscript.compiler.CompilationUnit;
5 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 9
 import org.openzen.zenscript.constructor.module.ModuleReference;
8 10
 
9 11
 public class Main {
@@ -18,12 +20,15 @@ public class Main {
18 20
 			return;
19 21
 		}
20 22
 		
23
+		Consumer<CompileException> exceptionLogger = exception -> System.err.println(exception.toString());
24
+		
21 25
 		File currentDirectory = new File(arguments.directory);
22 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 32
 		for (Library library : project.libraries) {
28 33
 			for (ModuleReference module : library.modules)
29 34
 				moduleLoader.register(module.getName(), module);

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

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

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

@@ -10,6 +10,8 @@ import java.util.HashMap;
10 10
 import java.util.HashSet;
11 11
 import java.util.Map;
12 12
 import java.util.Stack;
13
+import java.util.function.Consumer;
14
+import org.openzen.zencode.shared.CompileException;
13 15
 import org.openzen.zenscript.constructor.module.ModuleReference;
14 16
 import org.openzen.zenscript.compiler.SemanticModule;
15 17
 
@@ -25,9 +27,11 @@ public class ModuleLoader {
25 27
 	private final Stack<String> compilingModulesStack = new Stack<>();
26 28
 	
27 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 33
 		this.compilationUnit = compilationUnit;
34
+		this.exceptionLogger = exceptionLogger;
31 35
 	}
32 36
 	
33 37
 	public SemanticModule getModule(String name) {
@@ -49,7 +53,7 @@ public class ModuleLoader {
49 53
 		compilingModulesSet.add(name);
50 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 57
 		moduleCache.put(name, module);
54 58
 		
55 59
 		compilingModulesSet.remove(name);

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

@@ -9,9 +9,11 @@ import java.io.File;
9 9
 import java.io.IOException;
10 10
 import java.util.ArrayList;
11 11
 import java.util.List;
12
+import java.util.function.Consumer;
12 13
 import org.json.JSONArray;
13 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 17
 import org.openzen.zenscript.constructor.module.ModuleReference;
16 18
 import org.openzen.zenscript.compiler.Target;
17 19
 import org.openzen.zenscript.compiler.TargetType;
@@ -27,7 +29,7 @@ public class Project {
27 29
 	public final Library[] libraries;
28 30
 	public final Target[] targets;
29 31
 	
30
-	public Project(ModuleLoader loader, File directory) throws IOException {
32
+	public Project(File directory) throws IOException {
31 33
 		this.directory = directory;
32 34
 		name = directory.getName();
33 35
 		
@@ -46,7 +48,7 @@ public class Project {
46 48
 		libraries = new Library[jsonLibraries.length()];
47 49
 		int k = 0;
48 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 52
 			k++;
51 53
 		}
52 54
 		
@@ -55,13 +57,13 @@ public class Project {
55 57
 		for (int i = 0; i < jsonModules.length(); i++) {
56 58
 			Object module = jsonModules.get(i);
57 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 61
 			} else if (module instanceof JSONObject) {
60 62
 				JSONObject jsonModule = (JSONObject) module;
61 63
 				String name = jsonModule.getString("name");
62 64
 				switch (jsonModule.getString("type")) {
63 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 67
 						break;
66 68
 					default:
67 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,8 +10,10 @@ import java.io.File;
10 10
 import java.io.IOException;
11 11
 import java.util.ArrayList;
12 12
 import java.util.List;
13
+import java.util.function.Consumer;
13 14
 import org.json.JSONArray;
14 15
 import org.json.JSONObject;
16
+import org.openzen.zencode.shared.CompileException;
15 17
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
16 18
 import org.openzen.zenscript.compiler.CompilationUnit;
17 19
 import org.openzen.zenscript.constructor.ConstructorException;
@@ -25,15 +27,13 @@ import org.openzen.zenscript.parser.ParsedFile;
25 27
  *
26 28
  * @author Hoofdgebruiker
27 29
  */
28
-public class DirectoryModuleLoader implements ModuleReference {
29
-	private final ModuleLoader loader;
30
+public class DirectoryModuleReference implements ModuleReference {
30 31
 	private final String moduleName;
31 32
 	private final File directory;
32 33
 	private final boolean isStdlib;
33 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 37
 		this.moduleName = moduleName;
38 38
 		this.directory = directory;
39 39
 		this.isStdlib = isStdlib;
@@ -45,7 +45,7 @@ public class DirectoryModuleLoader implements ModuleReference {
45 45
 	}
46 46
 
47 47
 	@Override
48
-	public SemanticModule load(CompilationUnit unit) {
48
+	public SemanticModule load(ModuleLoader loader, CompilationUnit unit, Consumer<CompileException> exceptionLogger) {
49 49
 		if (!directory.exists())
50 50
 			throw new ConstructorException("Error: module directory not found: " + directory);
51 51
 		
@@ -71,11 +71,11 @@ public class DirectoryModuleLoader implements ModuleReference {
71 71
 			for (String dependencyName : dependencyNames)
72 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 75
 			ZSPackage pkg = isStdlib ? unit.globalTypeRegistry.stdlib : new ZSPackage(null, module.packageName);
76 76
 
77 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 80
 			JSONObject globals = json.optJSONObject("globals");
81 81
 			if (globals != null) {

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

@@ -5,8 +5,11 @@
5 5
  */
6 6
 package org.openzen.zenscript.constructor.module;
7 7
 
8
+import java.util.function.Consumer;
9
+import org.openzen.zencode.shared.CompileException;
8 10
 import org.openzen.zenscript.compiler.SemanticModule;
9 11
 import org.openzen.zenscript.compiler.CompilationUnit;
12
+import org.openzen.zenscript.constructor.ModuleLoader;
10 13
 
11 14
 /**
12 15
  *
@@ -15,7 +18,7 @@ import org.openzen.zenscript.compiler.CompilationUnit;
15 18
 public interface ModuleReference {
16 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 23
 	public SourcePackage getRootPackage();
21 24
 }

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

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import java.io.Closeable;
9 8
 import org.openzen.drawablegui.draw.DDrawSurface;
10 9
 import org.openzen.drawablegui.live.LiveObject;
11 10
 import org.openzen.drawablegui.style.DStylePath;
@@ -14,7 +13,7 @@ import org.openzen.drawablegui.style.DStylePath;
14 13
  *
15 14
  * @author Hoofdgebruiker
16 15
  */
17
-public interface DComponent extends Closeable {
16
+public interface DComponent extends Destructible {
18 17
 	void mount(DStylePath parent, int z, DDrawSurface surface);
19 18
 	
20 19
 	void unmount();
@@ -56,7 +55,4 @@ public interface DComponent extends Closeable {
56 55
 	default void onKeyPressed(DKeyEvent e) {}
57 56
 	
58 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,4 +19,8 @@ public interface DFontMetrics {
19 19
 	int getWidth(String str);
20 20
 	
21 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,6 +101,8 @@ public class DSimpleTooltipComponent implements DComponent {
101 101
 		fontMetrics = surface.getFontMetrics(style.font);
102 102
 		calculateSize();
103 103
 		
104
+		if (text != null)
105
+			text.close();
104 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

@@ -0,0 +1,22 @@
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,19 +5,16 @@
5 5
  */
6 6
 package org.openzen.drawablegui.draw;
7 7
 
8
-import java.io.Closeable;
9 8
 import org.openzen.drawablegui.DIRectangle;
10 9
 import org.openzen.drawablegui.DTransform2D;
10
+import org.openzen.drawablegui.Destructible;
11 11
 
12 12
 /**
13 13
  *
14 14
  * @author Hoofdgebruiker
15 15
  */
16
-public interface DDrawnElement extends Closeable {
16
+public interface DDrawnElement extends Destructible {
17 17
 	void setTransform(DTransform2D transform);
18 18
 	
19 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,8 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.live;
7 7
 
8
-import java.io.Closeable;
9 8
 import java.util.Iterator;
9
+import org.openzen.drawablegui.Destructible;
10 10
 import org.openzen.drawablegui.listeners.ListenerHandle;
11 11
 import org.openzen.drawablegui.listeners.ListenerList;
12 12
 
@@ -14,7 +14,7 @@ import org.openzen.drawablegui.listeners.ListenerList;
14 14
  *
15 15
  * @author Hoofdgebruiker
16 16
  */
17
-public class LiveConcatList<T> implements Closeable, LiveList<T> {
17
+public class LiveConcatList<T> implements Destructible, LiveList<T> {
18 18
 	private final ListenerList<Listener<T>> listeners = new ListenerList<>();
19 19
 	private final LiveList<T> a;
20 20
 	private final LiveList<T> b;

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

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

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

@@ -5,8 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.live;
7 7
 
8
-import java.io.Closeable;
9 8
 import java.util.function.Predicate;
9
+import org.openzen.drawablegui.Destructible;
10 10
 import org.openzen.drawablegui.listeners.ListenerHandle;
11 11
 import org.openzen.drawablegui.listeners.ListenerList;
12 12
 
@@ -14,7 +14,7 @@ import org.openzen.drawablegui.listeners.ListenerList;
14 14
  *
15 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 18
 	private final ListenerList<LiveBool.Listener> listeners = new ListenerList<>();
19 19
 	private final LiveObject<T> source;
20 20
 	private final Predicate<T> predicate;

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

@@ -24,7 +24,6 @@ import org.openzen.drawablegui.DUIWindow;
24 24
 import org.openzen.drawablegui.draw.DDrawSurface;
25 25
 import org.openzen.drawablegui.draw.DDrawnShape;
26 26
 import org.openzen.drawablegui.draw.DSubSurface;
27
-import org.openzen.drawablegui.live.MutableLiveObject;
28 27
 import org.openzen.drawablegui.style.DStyleClass;
29 28
 import org.openzen.drawablegui.style.DStylePath;
30 29
 import org.openzen.drawablegui.style.DStyleSheets;
@@ -47,23 +46,21 @@ public class DScrollPane implements DComponent {
47 46
 	private final LiveInt offsetX;
48 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 51
 	private final ListenerHandle<LiveInt.Listener> contentsHeightListener;
54 52
 	private final ListenerHandle<LiveInt.Listener> offsetXListener;
55 53
 	private final ListenerHandle<LiveInt.Listener> offsetYListener;
56
-	private final ListenerHandle<LiveInt.Listener> preferredHeightListener;
57 54
 	private final ListenerHandle<LiveObject.Listener<DSizing>> contentsSizingListener;
58 55
 	
59 56
 	private DComponent hovering = null;
60 57
 	
61 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 62
 		this.styleClass = styleClass;
65 63
 		this.contents = contents;
66
-		this.preferredHeight = preferredHeight;
67 64
 		
68 65
 		contentsHeight = new SimpleLiveInt(0);
69 66
 		offsetX = new SimpleLiveInt(0);
@@ -75,19 +72,13 @@ public class DScrollPane implements DComponent {
75 72
 		offsetXListener = offsetX.addListener(new ScrollListener());
76 73
 		offsetYListener = offsetY.addListener(new ScrollListener());
77 74
 		
78
-		contents.getSizing().addListener((oldPreferences, newPreferences) -> {
75
+		contentsSizingListener = contents.getSizing().addListener((oldPreferences, newPreferences) -> {
79 76
 			if (bounds == null)
80 77
 				return;
81 78
 			
82 79
 			contents.setBounds(new DIRectangle(0, 0, bounds.width, Math.max(bounds.height, newPreferences.preferredHeight)));
83 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 84
 	@Override
@@ -103,10 +94,11 @@ public class DScrollPane implements DComponent {
103 94
 	@Override
104 95
 	public void mount(DStylePath parent, int z, DDrawSurface surface) {
105 96
 		this.surface = surface;
97
+		this.z = z;
106 98
 		
107 99
 		DStylePath path = parent.getChild("scrollpane", styleClass);
108 100
 		subSurface = surface.createSubSurface(z + 1);
109
-		contents.mount(path, 0, subSurface);
101
+		contents.mount(path, 1, subSurface);
110 102
 		scrollBar.mount(path, z + 2, surface);
111 103
 		style = new DScrollPaneStyle(surface.getStylesheet(path));
112 104
 	}
@@ -143,7 +135,8 @@ public class DScrollPane implements DComponent {
143 135
 		shape = surface.shadowPath(z, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
144 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 140
 				contents.getSizing().getValue().preferredHeight);
148 141
 		int scrollBarWidth = scrollBar.getSizing().getValue().preferredWidth;
149 142
 		scrollBar.setBounds(new DIRectangle(
@@ -156,10 +149,10 @@ public class DScrollPane implements DComponent {
156 149
 		
157 150
 		subSurface.setOffset(bounds.x - offsetX.getValue(), bounds.y - offsetY.getValue());
158 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 158
 	@Override
@@ -228,6 +221,11 @@ public class DScrollPane implements DComponent {
228 221
 	public void close() {
229 222
 		contents.close();
230 223
 		unmount();
224
+		
225
+		contentsSizingListener.close();
226
+		contentsHeightListener.close();
227
+		offsetXListener.close();
228
+		offsetYListener.close();
231 229
 	}
232 230
 	
233 231
 	private DMouseEvent forward(DComponent target, DMouseEvent e) {
@@ -271,90 +269,6 @@ public class DScrollPane implements DComponent {
271 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 272
 	private class ScrollListener implements LiveInt.Listener {
359 273
 
360 274
 		@Override

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

@@ -46,8 +46,9 @@ public class SwingSubSurface extends SwingDrawnElement implements DSubSurface {
46 46
 		
47 47
 		AffineTransform oldTransform = g.getTransform();
48 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 52
 		g.setTransform(oldTransform);
52 53
 		g.setClip(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
53 54
 	}
@@ -75,7 +76,7 @@ public class SwingSubSurface extends SwingDrawnElement implements DSubSurface {
75 76
 	
76 77
 	@Override
77 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 82
 	@Override

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

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

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

@@ -24,10 +24,7 @@ public class Main {
24 24
 		Arguments arguments = new Arguments(args);
25 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 28
 		DevelopmentHost host = new LocalProjectDevelopmentHost(project);
32 29
 		open(host);
33 30
     }

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

@@ -5,6 +5,9 @@
5 5
  */
6 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 13
  * @author Hoofdgebruiker
@@ -16,7 +19,7 @@ public interface IDETarget {
16 19
 	
17 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,19 +6,23 @@
6 6
 package org.openzen.zenscript.ide.host.local;
7 7
 
8 8
 import java.io.File;
9
-import java.io.IOException;
10 9
 import java.util.HashSet;
11 10
 import java.util.Set;
11
+import java.util.function.Consumer;
12 12
 import org.openzen.zenscript.compiler.Target;
13 13
 import org.openzen.zenscript.compiler.ZenCodeCompiler;
14 14
 import org.openzen.zenscript.constructor.Library;
15 15
 import org.openzen.zenscript.constructor.ModuleLoader;
16 16
 import org.openzen.zenscript.constructor.Project;
17
-import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
17
+import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
18 18
 import org.openzen.zenscript.constructor.module.ModuleReference;
19 19
 import org.openzen.zenscript.compiler.SemanticModule;
20 20
 import org.openzen.zenscript.compiler.CompilationUnit;
21 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,25 +53,30 @@ public class LocalTarget implements IDETarget {
49 53
 	}
50 54
 
51 55
 	@Override
52
-	public void build() {
53
-		buildInternal();
56
+	public void build(Consumer<OutputLine> output) {
57
+		buildInternal(output);
54 58
 	}
55 59
 
56 60
 	@Override
57
-	public void run() {
58
-		ZenCodeCompiler compiler = buildInternal();
61
+	public void run(Consumer<OutputLine> output) {
62
+		ZenCodeCompiler compiler = buildInternal(output);
59 63
 		if (compiler != null)
60 64
 			compiler.run();
61 65
 	}
62 66
 	
63
-	private ZenCodeCompiler buildInternal() {
67
+	private ZenCodeCompiler buildInternal(Consumer<OutputLine> output) {
64 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 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 79
 		try {
70
-			Project project = new Project(moduleLoader, this.project.directory);
71 80
 			for (Library library : project.libraries) {
72 81
 				for (ModuleReference module : library.modules)
73 82
 					moduleLoader.register(module.getName(), module);
@@ -78,7 +87,7 @@ public class LocalTarget implements IDETarget {
78 87
 			
79 88
 			SemanticModule module = moduleLoader.getModule(target.getModule());
80 89
 			module = module.normalize();
81
-			module.validate();
90
+			module.validate(validationLogger);
82 91
 			
83 92
 			ZenCodeCompiler compiler = target.createCompiler(module);
84 93
 			if (!module.isValid())
@@ -86,37 +95,50 @@ public class LocalTarget implements IDETarget {
86 95
 			
87 96
 			SemanticModule stdlib = moduleLoader.getModule("stdlib");
88 97
 			stdlib = stdlib.normalize();
89
-			stdlib.validate();
98
+			stdlib.validate(validationLogger);
90 99
 			if (!stdlib.isValid())
91 100
 				return compiler;
92 101
 			stdlib.compile(compiler);
93 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 105
 			if (!isValid)
97 106
 				return compiler;
98 107
 			
99 108
 			module.compile(compiler);
100 109
 			compiler.finish();
101 110
 			return compiler;
102
-		} catch (IOException ex) {
111
+		} catch (Exception ex) {
103 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 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 131
 		for (String dependency : module.dependencies) {
110 132
 			if (compiledModules.contains(module.name))
111 133
 				continue;
112 134
 			
113 135
 			SemanticModule dependencyModule = loader.getModule(dependency);
114 136
 			module = module.normalize();
115
-			module.validate();
137
+			module.validate(logger);
116 138
 			if (!module.isValid())
117 139
 				return false;
118 140
 			
119
-			if (!compileDependencies(loader, compiler, compiledModules, dependencyModule))
141
+			if (!compileDependencies(loader, compiler, compiledModules, dependencyModule, logger))
120 142
 				return false;
121 143
 			
122 144
 			module.compile(compiler);

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

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

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

@@ -96,9 +96,6 @@ public class TabbedViewTabClose implements DComponent {
96 96
 		drawnIcon = new DColorableIconInstance(surface, z + 1, icon, DTransform2D.translate(
97 97
 				bounds.x + (bounds.width - icon.getNominalWidth()) / 2,
98 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 101
 	@Override

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

@@ -6,11 +6,15 @@
6 6
 package org.openzen.zenscript.ide.ui.view;
7 7
 
8 8
 import org.openzen.drawablegui.DEmptyView;
9
+import org.openzen.drawablegui.DSizing;
9 10
 import org.openzen.drawablegui.border.DLineBorder;
10 11
 import org.openzen.drawablegui.scroll.DScrollPane;
11 12
 import org.openzen.drawablegui.layout.DSideLayout;
13
+import org.openzen.drawablegui.live.LiveArrayList;
12 14
 import org.openzen.drawablegui.live.LiveString;
15
+import org.openzen.drawablegui.live.MutableLiveList;
13 16
 import org.openzen.drawablegui.live.SimpleLiveInt;
17
+import org.openzen.drawablegui.live.SimpleLiveObject;
14 18
 import org.openzen.drawablegui.live.SimpleLiveString;
15 19
 import org.openzen.drawablegui.style.DShadow;
16 20
 import org.openzen.drawablegui.style.DStyleClass;
@@ -21,6 +25,8 @@ import org.openzen.zenscript.ide.ui.IDEDockWindow;
21 25
 import org.openzen.zenscript.ide.ui.IDEWindow;
22 26
 import org.openzen.zenscript.ide.ui.view.aspectbar.AspectBarView;
23 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 30
 import org.openzen.zenscript.ide.ui.view.project.ProjectBrowser;
25 31
 
26 32
 /**
@@ -41,9 +47,19 @@ public final class WindowView extends DSideLayout {
41 47
 		
42 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 59
 		setMain(tabs = new TabbedView(DStyleClass.inline(new DStylesheetBuilder()
45 60
 				.marginDp("margin", 3)
46 61
 				.build())));
62
+		add(Side.BOTTOM, scrollOutput);
47 63
 		add(Side.LEFT, projectBrowser.view);
48 64
 		add(Side.BOTTOM, new StatusBarView(DStyleClass.EMPTY, status));
49 65
 		add(Side.TOP, new AspectBarView(DStyleClass.EMPTY, window.aspectBar));
@@ -61,7 +77,7 @@ public final class WindowView extends DSideLayout {
61 77
 					new DScrollPane(DStyleClass.inline(new DStylesheetBuilder()
62 78
 							.border("border", context -> new DLineBorder(0xFF888888, 1))
63 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 81
 					editor.isUpdated());
66 82
 			tabs.tabs.add(tab);
67 83
 			tabs.currentTab.setValue(tab);

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

@@ -20,4 +20,14 @@ public class BasicOutputSpan implements OutputSpan {
20 20
 	public String toString() {
21 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,6 +5,8 @@
5 5
  */
6 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 12
  * @author Hoofdgebruiker
@@ -20,4 +22,14 @@ public class ErrorOutputSpan implements OutputSpan {
20 22
 	public String toString() {
21 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,6 +12,14 @@ package org.openzen.zenscript.ide.ui.view.output;
12 12
 public class OutputLine {
13 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 23
 	public OutputLine(OutputSpan[] spans) {
16 24
 		this.spans = spans;
17 25
 	}

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

@@ -10,5 +10,7 @@ package org.openzen.zenscript.ide.ui.view.output;
10 10
  * @author Hoofdgebruiker
11 11
  */
12 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,13 +5,20 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.ui.view.output;
7 7
 
8
+import java.util.ArrayList;
9
+import java.util.List;
8 10
 import org.openzen.drawablegui.DComponent;
11
+import org.openzen.drawablegui.DFontMetrics;
9 12
 import org.openzen.drawablegui.DIRectangle;
10 13
 import org.openzen.drawablegui.DSizing;
11 14
 import org.openzen.drawablegui.DTransform2D;
15
+import org.openzen.drawablegui.Destructible;
12 16
 import org.openzen.drawablegui.draw.DDrawSurface;
13 17
 import org.openzen.drawablegui.draw.DDrawnShape;
18
+import org.openzen.drawablegui.draw.DDrawnText;
19
+import org.openzen.drawablegui.listeners.ListenerHandle;
14 20
 import org.openzen.drawablegui.live.LiveList;
21
+import org.openzen.drawablegui.live.LiveObject;
15 22
 import org.openzen.drawablegui.live.MutableLiveObject;
16 23
 import org.openzen.drawablegui.style.DStyleClass;
17 24
 import org.openzen.drawablegui.style.DStylePath;
@@ -29,8 +36,11 @@ public class OutputView implements DComponent {
29 36
 	private int z;
30 37
 	private DIRectangle bounds;
31 38
 	private OutputViewStyle style;
39
+	private DFontMetrics fontMetrics;
40
+	private ListenerHandle<LiveList.Listener<OutputLine>> linesListener;
32 41
 	
33 42
 	private DDrawnShape shape;
43
+	private final List<List<DDrawnText>> outputText = new ArrayList<>();
34 44
 	
35 45
 	public OutputView(DStyleClass styleClass, LiveList<OutputLine> lines) {
36 46
 		this.styleClass = styleClass;
@@ -39,23 +49,41 @@ public class OutputView implements DComponent {
39 49
 
40 50
 	@Override
41 51
 	public void mount(DStylePath parent, int z, DDrawSurface surface) {
52
+		if (this.surface != null)
53
+			unmount();
54
+		
42 55
 		this.surface = surface;
43 56
 		this.z = z;
44 57
 		
45 58
 		DStylePath path = parent.getChild("outputview", styleClass);
46 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 69
 	@Override
50 70
 	public void unmount() {
71
+		surface = null;
72
+		
51 73
 		if (shape != null) {
52 74
 			shape.close();
53 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 85
 	@Override
58
-	public MutableLiveObject<DSizing> getSizing() {
86
+	public LiveObject<DSizing> getSizing() {
59 87
 		return sizing;
60 88
 	}
61 89
 
@@ -72,11 +100,62 @@ public class OutputView implements DComponent {
72 100
 	@Override
73 101
 	public void setBounds(DIRectangle bounds) {
74 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 110
 	@Override
79 111
 	public void close() {
80 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,29 +7,20 @@ package org.openzen.zenscript.ide.ui.view.output;
7 7
 
8 8
 import org.openzen.drawablegui.DFont;
9 9
 import org.openzen.drawablegui.DFontFamily;
10
-import org.openzen.drawablegui.border.DBorder;
11 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 12
 import org.openzen.drawablegui.style.DStyleDefinition;
16 13
 
17 14
 /**
18 15
  *
19 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 19
 	public final DFont font;
27 20
 	
28 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 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,6 +6,9 @@
6 6
 package org.openzen.zenscript.ide.ui.view.project;
7 7
 
8 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 12
 import org.openzen.drawablegui.DSizing;
10 13
 import org.openzen.drawablegui.border.DEmptyBorder;
11 14
 import org.openzen.drawablegui.border.DPaddedBorder;
@@ -18,8 +21,8 @@ import org.openzen.drawablegui.live.ImmutableLiveString;
18 21
 import org.openzen.drawablegui.live.LiveBool;
19 22
 import org.openzen.drawablegui.live.LivePredicateBool;
20 23
 import org.openzen.drawablegui.live.MutableLiveObject;
21
-import org.openzen.drawablegui.live.SimpleLiveInt;
22 24
 import org.openzen.drawablegui.live.SimpleLiveObject;
25
+import org.openzen.drawablegui.live.SimpleLiveString;
23 26
 import org.openzen.drawablegui.scroll.DScrollPane;
24 27
 import org.openzen.drawablegui.style.DRoundedRectangleShape;
25 28
 import org.openzen.drawablegui.style.DShadow;
@@ -27,7 +30,6 @@ import org.openzen.drawablegui.style.DStyleClass;
27 30
 import org.openzen.drawablegui.style.DStylesheetBuilder;
28 31
 import org.openzen.drawablegui.tree.CollapsedArrow;
29 32
 import org.openzen.drawablegui.tree.DTreeView;
30
-import org.openzen.drawablegui.tree.DTreeViewStyle;
31 33
 import org.openzen.drawablegui.tree.ExpandedArrow;
32 34
 import org.openzen.zenscript.ide.host.DevelopmentHost;
33 35
 import org.openzen.zenscript.ide.host.IDEModule;
@@ -60,6 +62,12 @@ public class ProjectBrowser {
60 62
 				.dimensionDp("padding", 0)
61 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 71
 		IconButtonControl addPackageButton = new IconButtonControl(
64 72
 				minimalButtonPadding,
65 73
 				AddBoxIcon.BLUE,
@@ -91,6 +99,7 @@ public class ProjectBrowser {
91 99
 						.build()),
92 100
 				Orientation.HORIZONTAL,
93 101
 				Alignment.LEFT,
102
+				new Element(label, 1, 1, ElementAlignment.CENTER),
94 103
 				new Element(addPackageButton, 0, 0, ElementAlignment.TOP),
95 104
 				new Element(addFileButton, 0, 0, ElementAlignment.TOP));
96 105
 		DTreeView projectTree = new DTreeView(
@@ -98,7 +107,6 @@ public class ProjectBrowser {
98 107
 				ExpandedArrow.INSTANCE,
99 108
 				CollapsedArrow.INSTANCE,
100 109
 				new RootTreeNode(this, host), false);
101
-		projectTree.getSizing().setValue(new DSizing(500, 500));
102 110
 		DScrollPane treeScrollPane = new DScrollPane(
103 111
 				DStyleClass.inline("projectView", new DStylesheetBuilder()
104 112
 						.shape("shape", context -> new DRoundedRectangleShape(0, 0, context.dp(2), context.dp(2)))
@@ -106,7 +114,7 @@ public class ProjectBrowser {
106 114
 						.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
107 115
 						.build()),
108 116
 				projectTree,
109
-				new SimpleLiveInt(0));
117
+				new SimpleLiveObject<>(new DSizing(500, 500)));
110 118
 		
111 119
 		view = new DLinearLayout(
112 120
 				DStyleClass.inline(new DStylesheetBuilder()

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

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

Loading…
Cancel
Save