Browse Source

Merge remote-tracking branch 'Stan/development' into development

kindlich 6 years ago
parent
commit
30b3e612e2
No known key found for this signature in database
70 changed files with 835 additions and 528 deletions
  1. 6
    4
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FileFormatter.java
  2. 0
    15
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  3. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ConstExpression.java
  4. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/Expression.java
  5. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/GetFieldExpression.java
  6. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/GetStaticFieldExpression.java
  7. 10
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/IPartialExpression.java
  8. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java
  9. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java
  10. 6
    4
      Constructor/src/main/java/org/openzen/zenscript/constructor/Module.java
  11. 14
    20
      DrawableGui/src/main/java/org/openzen/drawablegui/DButton.java
  12. 1
    7
      DrawableGui/src/main/java/org/openzen/drawablegui/DComponent.java
  13. 92
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/DComponentContext.java
  14. 1
    3
      DrawableGui/src/main/java/org/openzen/drawablegui/DEmptyView.java
  15. 18
    24
      DrawableGui/src/main/java/org/openzen/drawablegui/DInputField.java
  16. 9
    16
      DrawableGui/src/main/java/org/openzen/drawablegui/DLabel.java
  17. 11
    17
      DrawableGui/src/main/java/org/openzen/drawablegui/DSimpleTooltipComponent.java
  18. 0
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/DUIContext.java
  19. 2
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DBorder.java
  20. 3
    3
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DCompositeBorder.java
  21. 12
    16
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DCustomWindowBorder.java
  22. 2
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DEmptyBorder.java
  23. 3
    3
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DLineBorder.java
  24. 2
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DPaddedBorder.java
  25. 6
    6
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DSideBorder.java
  26. 8
    11
      DrawableGui/src/main/java/org/openzen/drawablegui/form/DForm.java
  27. 11
    19
      DrawableGui/src/main/java/org/openzen/drawablegui/layout/DLinearLayout.java
  28. 12
    17
      DrawableGui/src/main/java/org/openzen/drawablegui/layout/DSideLayout.java
  29. 6
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveArrayList.java
  30. 2
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/live/MutableLiveList.java
  31. 7
    10
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollBar.java
  32. 18
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollContext.java
  33. 33
    34
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java
  34. 10
    10
      DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingGraphicsContext.java
  35. 2
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingRoot.java
  36. 15
    15
      DrawableGui/src/main/java/org/openzen/drawablegui/tree/DTreeView.java
  37. 6
    1
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java
  38. 1
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEWindow.java
  39. 1
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/dialog/CreateSourceFileDialog.java
  40. 17
    22
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/IconButtonControl.java
  41. 9
    14
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/StatusBarView.java
  42. 14
    22
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedView.java
  43. 15
    18
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTab.java
  44. 8
    13
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabClose.java
  45. 16
    19
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarSelectorButton.java
  46. 41
    45
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarView.java
  47. 11
    15
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/WindowActionButton.java
  48. 64
    55
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java
  49. 10
    15
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputView.java
  50. 8
    4
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenParser.java
  51. 27
    0
      Parser/src/main/java/org/openzen/zenscript/parser/BracketExpressionParser.java
  52. 2
    0
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedDefinition.java
  53. 9
    7
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java
  54. 57
    0
      Parser/src/main/java/org/openzen/zenscript/parser/PrefixedBracketParser.java
  55. 73
    0
      Parser/src/main/java/org/openzen/zenscript/parser/SimpleBracketSubParser.java
  56. 7
    0
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/BaseParsedDefinition.java
  57. 5
    0
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedAlias.java
  58. 8
    5
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedFunction.java
  59. 6
    0
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java
  60. 2
    2
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java
  61. 11
    1
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionVariable.java
  62. 5
    1
      Parser/src/main/java/org/openzen/zenscript/parser/type/ParsedNamedType.java
  63. 2
    0
      ScriptingExample/scripts/ttt/helloworld.zs
  64. 22
    1
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java
  65. 3
    1
      Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java
  66. 10
    2
      Shared/src/main/java/org/openzen/zencode/shared/FileSourceFile.java
  67. 5
    0
      Shared/src/main/java/org/openzen/zencode/shared/LiteralSourceFile.java
  68. 2
    0
      Shared/src/main/java/org/openzen/zencode/shared/SourceFile.java
  69. 5
    0
      Shared/src/main/java/org/openzen/zencode/shared/VirtualSourceFile.java
  70. 1
    1
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ValidationUtils.java

+ 6
- 4
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FileFormatter.java View File

@@ -43,9 +43,11 @@ public class FileFormatter {
43 43
 		}
44 44
 		
45 45
 		StringBuilder scriptOutput = new StringBuilder();
46
-		StatementFormatter scriptFormatter = new StatementFormatter(scriptOutput, "", settings, expressionFormatter);
47
-		for (Statement statement : script.statements) {
48
-			statement.accept(scriptFormatter);
46
+		if (script != null) {
47
+			StatementFormatter scriptFormatter = new StatementFormatter(scriptOutput, "", settings, expressionFormatter);
48
+			for (Statement statement : script.statements) {
49
+				statement.accept(scriptFormatter);
50
+			}
49 51
 		}
50 52
 		
51 53
 		StringBuilder output = new StringBuilder();
@@ -61,7 +63,7 @@ public class FileFormatter {
61 63
 			output.append(definition.toString());
62 64
 		}
63 65
 		
64
-		if (script.statements.size() > 0) {
66
+		if (script != null && script.statements.size() > 0) {
65 67
 			if (definitionFormatters.size() > 0)
66 68
 				output.append("\n");
67 69
 			

+ 0
- 15
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java View File

@@ -229,21 +229,6 @@ public class FunctionHeader {
229 229
 		return false;
230 230
 	}
231 231
 	
232
-	public boolean canCastTo(TypeScope scope, FunctionHeader header) {
233
-		if (parameters.length != header.parameters.length)
234
-			return false;
235
-		
236
-		if (!scope.getTypeMembers(returnType).canCastImplicit(header.returnType))
237
-			return false;
238
-		
239
-		for (int i = 0; i < parameters.length; i++) {
240
-			if (!scope.getTypeMembers(header.parameters[i].type).canCastImplicit(parameters[i].type))
241
-				return false;
242
-		}
243
-		
244
-		return true;
245
-	}
246
-	
247 232
 	public boolean accepts(TypeScope scope, Expression... arguments) {
248 233
 		if (parameters.length != arguments.length)
249 234
 			return false;

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ConstExpression.java View File

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.expression;
7 7
 
8 8
 import org.openzen.zencode.shared.CodePosition;
9 9
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
10
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
10 11
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
11 12
 
12 13
 /**
@@ -41,4 +42,9 @@ public class ConstExpression extends Expression {
41 42
 	public EnumConstantMember evaluateEnumConstant() {
42 43
 		return constant.member.value.evaluateEnumConstant();
43 44
 	}
45
+	
46
+	@Override
47
+	public IDefinitionMember getMember() {
48
+		return constant.member;
49
+	}
44 50
 }

+ 3
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/Expression.java View File

@@ -22,6 +22,7 @@ import org.openzen.zenscript.codemodel.type.member.TypeMembers;
22 22
 import org.openzen.zenscript.codemodel.scope.TypeScope;
23 23
 import org.openzen.zenscript.codemodel.statement.Statement;
24 24
 import org.openzen.zenscript.codemodel.statement.StatementTransformer;
25
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
25 26
 import org.openzen.zenscript.codemodel.type.FunctionTypeID;
26 27
 
27 28
 /**
@@ -38,6 +39,8 @@ public abstract class Expression implements IPartialExpression {
38 39
 	public Expression(CodePosition position, ITypeID type, ITypeID thrownType) {
39 40
 		if (type == null)
40 41
 			throw new NullPointerException();
42
+		if (type == BasicTypeID.UNDETERMINED)
43
+			throw new IllegalArgumentException("Cannot use undetermined type as expression type");
41 44
 		
42 45
 		this.position = position;
43 46
 		this.type = type;

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/GetFieldExpression.java View File

@@ -8,6 +8,7 @@ package org.openzen.zenscript.codemodel.expression;
8 8
 import java.util.Collections;
9 9
 import java.util.List;
10 10
 import org.openzen.zencode.shared.CodePosition;
11
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
11 12
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
12 13
 import org.openzen.zenscript.codemodel.scope.TypeScope;
13 14
 import org.openzen.zenscript.codemodel.type.ITypeID;
@@ -52,4 +53,9 @@ public class GetFieldExpression extends Expression {
52 53
 		Expression tTarget = target.transform(transformer);
53 54
 		return tTarget == target ? this : new GetFieldExpression(position, tTarget, field);
54 55
 	}
56
+	
57
+	@Override
58
+	public IDefinitionMember getMember() {
59
+		return field.member;
60
+	}
55 61
 }

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/GetStaticFieldExpression.java View File

@@ -8,6 +8,7 @@ package org.openzen.zenscript.codemodel.expression;
8 8
 import java.util.Collections;
9 9
 import java.util.List;
10 10
 import org.openzen.zencode.shared.CodePosition;
11
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
11 12
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
12 13
 import org.openzen.zenscript.codemodel.type.ITypeID;
13 14
 
@@ -43,4 +44,9 @@ public class GetStaticFieldExpression extends Expression {
43 44
 	public Expression transform(ExpressionTransformer transformer) {
44 45
 		return this;
45 46
 	}
47
+	
48
+	@Override
49
+	public IDefinitionMember getMember() {
50
+		return field.member;
51
+	}
46 52
 }

+ 10
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/IPartialExpression.java View File

@@ -14,6 +14,7 @@ import org.openzen.zenscript.codemodel.FunctionHeader;
14 14
 import org.openzen.zenscript.codemodel.expression.CallArguments;
15 15
 import org.openzen.zenscript.codemodel.expression.Expression;
16 16
 import org.openzen.zenscript.codemodel.expression.LambdaClosure;
17
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
17 18
 import org.openzen.zenscript.codemodel.type.GenericName;
18 19
 import org.openzen.zenscript.codemodel.type.ITypeID;
19 20
 import org.openzen.zenscript.codemodel.scope.TypeScope;
@@ -39,6 +40,15 @@ public interface IPartialExpression {
39 40
 	
40 41
 	ITypeID[] getGenericCallTypes();
41 42
 	
43
+	/**
44
+	 * Retrieves the (primary) member this expression refers to, or null if there is no primary target.
45
+	 * 
46
+	 * @return 
47
+	 */
48
+	default IDefinitionMember getMember() {
49
+		return null;
50
+	}
51
+	
42 52
 	default Expression assign(CodePosition position, TypeScope scope, Expression value) {
43 53
 		throw new CompileException(position, CompileExceptionCode.CANNOT_ASSIGN, "This expression is not assignable");
44 54
 	}

+ 3
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java View File

@@ -147,6 +147,9 @@ public class GlobalTypeRegistry {
147 147
 	}
148 148
 	
149 149
 	public OptionalTypeID getOptional(ITypeID original) {
150
+		if (original == null)
151
+			throw new NullPointerException("original cannot be null");
152
+		
150 153
 		if (optionalTypes.containsKey(original)) {
151 154
 			return optionalTypes.get(original);
152 155
 		} else {

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java View File

@@ -20,11 +20,17 @@ public class OptionalTypeID implements ITypeID {
20 20
 	public final ITypeID baseType;
21 21
 	
22 22
 	public OptionalTypeID(ITypeID baseType) {
23
+		if (baseType == null)
24
+			throw new NullPointerException("baseType cannot be null");
25
+		
23 26
 		this.baseType = baseType;
24 27
 	}
25 28
 	
26 29
 	@Override
27 30
 	public ITypeID instance(GenericMapper mapper) {
31
+		if (mapper == null)
32
+			throw new NullPointerException("mapper cannot be null");
33
+		
28 34
 		return mapper.registry.getModified(TypeMembers.MODIFIER_OPTIONAL, baseType.instance(mapper));
29 35
 	}
30 36
 

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

@@ -25,6 +25,7 @@ import org.openzen.zenscript.codemodel.definition.ZSPackage;
25 25
 import org.openzen.zenscript.constructor.module.ModuleSpace;
26 26
 import org.openzen.zenscript.compiler.SemanticModule;
27 27
 import org.openzen.zenscript.codemodel.type.ISymbol;
28
+import org.openzen.zenscript.parser.BracketExpressionParser;
28 29
 import org.openzen.zenscript.parser.ParsedFile;
29 30
 
30 31
 /**
@@ -59,21 +60,22 @@ public class Module {
59 60
 	}
60 61
 	
61 62
 	public ParsedFile[] parse(ZSPackage pkg) throws IOException {
63
+		// TODO: load bracket parsers from host plugins
62 64
 		List<ParsedFile> files = new ArrayList<>();
63
-		parse(files, pkg, sourceDirectory);
65
+		parse(files, pkg, null, sourceDirectory);
64 66
 		return files.toArray(new ParsedFile[files.size()]);
65 67
 	}
66 68
 	
67
-	private void parse(List<ParsedFile> files, ZSPackage pkg, File directory) throws IOException {
69
+	private void parse(List<ParsedFile> files, ZSPackage pkg, BracketExpressionParser bracketParser, File directory) throws IOException {
68 70
 		for (File file : directory.listFiles()) {
69 71
 			if (file.getName().endsWith(".zs")) {
70 72
 				try {
71
-					files.add(ParsedFile.parse(pkg, file));
73
+					files.add(ParsedFile.parse(pkg, bracketParser, file));
72 74
 				} catch (CompileException ex) {
73 75
 					exceptionLogger.accept(ex);
74 76
 				}
75 77
 			} else if (file.isDirectory()) {
76
-				parse(files, pkg.getOrCreatePackage(file.getName()), file);
78
+				parse(files, pkg.getOrCreatePackage(file.getName()), bracketParser, file);
77 79
 			}
78 80
 		}
79 81
 	}

+ 14
- 20
DrawableGui/src/main/java/org/openzen/drawablegui/DButton.java View File

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.draw.DDrawSurface;
9 8
 import org.openzen.drawablegui.draw.DDrawnShape;
10 9
 import org.openzen.drawablegui.draw.DDrawnText;
11 10
 import org.openzen.drawablegui.live.LiveBool;
@@ -14,7 +13,6 @@ import org.openzen.drawablegui.live.LiveString;
14 13
 import org.openzen.drawablegui.live.MutableLiveObject;
15 14
 import org.openzen.drawablegui.style.DShadow;
16 15
 import org.openzen.drawablegui.style.DStyleClass;
17
-import org.openzen.drawablegui.style.DStylePath;
18 16
 
19 17
 /**
20 18
  *
@@ -27,8 +25,7 @@ public class DButton implements DComponent {
27 25
 	private final LiveBool disabled;
28 26
 	private final Runnable action;
29 27
 	
30
-	private DDrawSurface surface;
31
-	private int z;
28
+	private DComponentContext context;
32 29
 	private DIRectangle bounds;
33 30
 	
34 31
 	private DButtonStyle style;
@@ -49,13 +46,10 @@ public class DButton implements DComponent {
49 46
 	}
50 47
 	
51 48
 	@Override
52
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
53
-		this.surface = surface;
54
-		this.z = z;
55
-		
56
-		DStylePath path = parent.getChild("Button", styleClass);
57
-		this.style = new DButtonStyle(surface.getStylesheet(path));
58
-		fontMetrics = surface.getFontMetrics(style.font);
49
+	public void mount(DComponentContext parent) {
50
+		context = parent.getChildContext("button", styleClass);
51
+		style = context.getStyle(DButtonStyle::new);
52
+		fontMetrics = context.getFontMetrics(style.font);
59 53
 		
60 54
 		sizing.setValue(new DSizing(
61 55
 				style.paddingLeft + style.paddingRight + fontMetrics.getWidth(label.getValue()),
@@ -65,7 +59,7 @@ public class DButton implements DComponent {
65 59
 	
66 60
 	@Override
67 61
 	public void unmount() {
68
-		surface = null;
62
+		context = null;
69 63
 		
70 64
 		if (shape != null)
71 65
 			shape.close();
@@ -97,14 +91,14 @@ public class DButton implements DComponent {
97 91
 		if (text != null)
98 92
 			text.close();
99 93
 		
100
-		shape = surface.shadowPath(
101
-				z,
102
-				DPath.roundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 2 * surface.getScale()),
94
+		shape = context.shadowPath(
95
+				0,
96
+				DPath.roundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 2 * context.getScale()),
103 97
 				DTransform2D.IDENTITY,
104 98
 				getBackgroundColor(),
105 99
 				currentShadow);
106
-		text = surface.drawText(
107
-				z +  1, 
100
+		text = context.drawText(
101
+				1, 
108 102
 				style.font,
109 103
 				style.textColor,
110 104
 				bounds.x + style.paddingLeft,
@@ -155,9 +149,9 @@ public class DButton implements DComponent {
155 149
 			if (shape != null)
156 150
 				shape.close();
157 151
 			
158
-			shape = surface.shadowPath(
159
-				z,
160
-				DPath.roundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 2 * surface.getScale()),
152
+			shape = context.shadowPath(
153
+				0,
154
+				DPath.roundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 2 * context.getScale()),
161 155
 				DTransform2D.IDENTITY,
162 156
 				getBackgroundColor(),
163 157
 				currentShadow);

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

@@ -5,16 +5,14 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.draw.DDrawSurface;
9 8
 import org.openzen.drawablegui.live.LiveObject;
10
-import org.openzen.drawablegui.style.DStylePath;
11 9
 
12 10
 /**
13 11
  *
14 12
  * @author Hoofdgebruiker
15 13
  */
16 14
 public interface DComponent extends Destructible {
17
-	void mount(DStylePath parent, int z, DDrawSurface surface);
15
+	void mount(DComponentContext context);
18 16
 	
19 17
 	void unmount();
20 18
 	
@@ -26,10 +24,6 @@ public interface DComponent extends Destructible {
26 24
 	
27 25
 	void setBounds(DIRectangle bounds);
28 26
 	
29
-	default void onMounted() {}
30
-	
31
-	default void onUnmounted() {}
32
-	
33 27
 	default void onMouseEnter(DMouseEvent e) {}
34 28
 	
35 29
 	default void onMouseExit(DMouseEvent e) {}

+ 92
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/DComponentContext.java View File

@@ -0,0 +1,92 @@
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.function.Function;
9
+import org.openzen.drawablegui.draw.DDrawSurface;
10
+import org.openzen.drawablegui.draw.DDrawnRectangle;
11
+import org.openzen.drawablegui.draw.DDrawnShape;
12
+import org.openzen.drawablegui.draw.DDrawnText;
13
+import org.openzen.drawablegui.draw.DSubSurface;
14
+import org.openzen.drawablegui.scroll.DScrollContext;
15
+import org.openzen.drawablegui.style.DShadow;
16
+import org.openzen.drawablegui.style.DStyleClass;
17
+import org.openzen.drawablegui.style.DStyleDefinition;
18
+import org.openzen.drawablegui.style.DStylePath;
19
+
20
+/**
21
+ *
22
+ * @author Hoofdgebruiker
23
+ */
24
+public class DComponentContext {
25
+	public final DScrollContext scrollContext;
26
+	public final DStylePath path;
27
+	public final int z;
28
+	public final DDrawSurface surface;
29
+	
30
+	public DComponentContext(DScrollContext scrollContext, DStylePath path, int z, DDrawSurface surface) {
31
+		this.scrollContext = scrollContext;
32
+		this.path = path;
33
+		this.z = z;
34
+		this.surface = surface;
35
+	}
36
+	
37
+	public DComponentContext getChildContext(String component, DStyleClass styleClass) {
38
+		return getChildContext(10, component, styleClass);
39
+	}
40
+	
41
+	public DComponentContext getChildContext(int deltaz, String component, DStyleClass styleClass) {
42
+		return new DComponentContext(scrollContext, path.getChild(component, styleClass), z + deltaz, surface);
43
+	}
44
+	
45
+	public DUIContext getUIContext() {
46
+		return surface.getContext();
47
+	}
48
+	
49
+	public DStyleDefinition getStyle() {
50
+		return surface.getStylesheet(path);
51
+	}
52
+	
53
+	public <S> S getStyle(Function<DStyleDefinition, S> factory) {
54
+		return factory.apply(surface.getStylesheet(path));
55
+	}
56
+
57
+	public DFontMetrics getFontMetrics(DFont font) {
58
+		return surface.getFontMetrics(font);
59
+	}
60
+	
61
+	public float getScale() {
62
+		return surface.getScale();
63
+	}
64
+	
65
+	public float getTextScale() {
66
+		return surface.getTextScale();
67
+	}
68
+	
69
+	public DDrawnText drawText(int deltaz, DFont font, int color, float x, float y, String text) {
70
+		return surface.drawText(z + deltaz, font, color, x, y, text);
71
+	}
72
+	
73
+	public DDrawnRectangle fillRect(int deltaz, DIRectangle rectangle, int color) {
74
+		return surface.fillRect(z + deltaz, rectangle, color);
75
+	}
76
+	
77
+	public DDrawnShape strokePath(int deltaz, DPath path, DTransform2D transform, int color, float lineWidth) {
78
+		return surface.strokePath(z + deltaz, path, transform, color, lineWidth);
79
+	}
80
+	
81
+	public DDrawnShape fillPath(int deltaz, DPath path, DTransform2D transform, int color) {
82
+		return surface.fillPath(z + deltaz, path, transform, color);
83
+	}
84
+	
85
+	public DDrawnShape shadowPath(int deltaz, DPath path, DTransform2D transform, int color, DShadow shadow) {
86
+		return surface.shadowPath(z + deltaz, path, transform, color, shadow);
87
+	}
88
+	
89
+	public DSubSurface createSubSurface(int deltaz) {
90
+		return surface.createSubSurface(z + deltaz);
91
+	}
92
+}

+ 1
- 3
DrawableGui/src/main/java/org/openzen/drawablegui/DEmptyView.java View File

@@ -5,10 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.draw.DDrawSurface;
9 8
 import org.openzen.drawablegui.live.ImmutableLiveObject;
10 9
 import org.openzen.drawablegui.live.LiveObject;
11
-import org.openzen.drawablegui.style.DStylePath;
12 10
 
13 11
 /**
14 12
  *
@@ -22,7 +20,7 @@ public class DEmptyView implements DComponent {
22 20
 	private DEmptyView() {}
23 21
 
24 22
 	@Override
25
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
23
+	public void mount(DComponentContext parent) {
26 24
 		
27 25
 	}
28 26
 	

+ 18
- 24
DrawableGui/src/main/java/org/openzen/drawablegui/DInputField.java View File

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.draw.DDrawSurface;
9 8
 import org.openzen.drawablegui.draw.DDrawnRectangle;
10 9
 import org.openzen.drawablegui.draw.DDrawnShape;
11 10
 import org.openzen.drawablegui.draw.DDrawnText;
@@ -16,7 +15,6 @@ import org.openzen.drawablegui.live.MutableLiveObject;
16 15
 import org.openzen.drawablegui.live.MutableLiveString;
17 16
 import org.openzen.drawablegui.style.DDimension;
18 17
 import org.openzen.drawablegui.style.DStyleClass;
19
-import org.openzen.drawablegui.style.DStylePath;
20 18
 
21 19
 /**
22 20
  *
@@ -31,8 +29,7 @@ public class DInputField implements DComponent {
31 29
 	private DIRectangle bounds = DIRectangle.EMPTY;
32 30
 	private final DDimension preferredWidth;
33 31
 	
34
-	private DDrawSurface surface;
35
-	private int z;
32
+	private DComponentContext context;
36 33
 	private DInputFieldStyle style;
37 34
 	private DFontMetrics fontMetrics;
38 35
 	private int cursorFrom = -1;
@@ -74,26 +71,23 @@ public class DInputField implements DComponent {
74 71
 	}
75 72
 
76 73
 	@Override
77
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
78
-		this.surface = surface;
79
-		this.z = z;
80
-		
81
-		DStylePath path = parent.getChild("input", styleClass);
82
-		style = new DInputFieldStyle(surface.getStylesheet(path));
83
-		fontMetrics = surface.getFontMetrics(style.font);
74
+	public void mount(DComponentContext parent) {
75
+		context = parent.getChildContext("input", styleClass);
76
+		style = context.getStyle(DInputFieldStyle::new);
77
+		fontMetrics = context.getFontMetrics(style.font);
84 78
 		
85 79
 		sizing.setValue(new DSizing(
86
-				preferredWidth.evalInt(surface.getContext()) + style.margin.getHorizontal() + style.border.getPaddingHorizontal(),
80
+				preferredWidth.evalInt(context.getUIContext()) + style.margin.getHorizontal() + style.border.getPaddingHorizontal(),
87 81
 				fontMetrics.getAscent() + fontMetrics.getDescent() + style.margin.getVertical() + style.border.getPaddingVertical()));
88 82
 		
89 83
 		if (blinkTimer != null)
90 84
 			blinkTimer.close();
91
-		blinkTimer = surface.getContext().setTimer(300, this::blink);
85
+		blinkTimer = context.getUIContext().setTimer(300, this::blink);
92 86
 		
93 87
 		if (text != null)
94 88
 			text.close();
95
-		text = surface.drawText(
96
-				z + 2,
89
+		text = parent.drawText(
90
+				2,
97 91
 				style.font,
98 92
 				style.color,
99 93
 				bounds.x + style.margin.left + style.border.getPaddingLeft(),
@@ -102,11 +96,11 @@ public class DInputField implements DComponent {
102 96
 		
103 97
 		if (cursor != null)
104 98
 			cursor.close();
105
-		cursor = surface.fillRect(z + 2, DIRectangle.EMPTY, cursorBlink ? style.cursorColor : 0);
99
+		cursor = parent.fillRect(2, DIRectangle.EMPTY, cursorBlink ? style.cursorColor : 0);
106 100
 		
107 101
 		if (selection != null)
108 102
 			selection.close();
109
-		selection = surface.fillRect(z + 1, DIRectangle.EMPTY, 0);
103
+		selection = parent.fillRect(1, DIRectangle.EMPTY, 0);
110 104
 		
111 105
 		setCursor(cursorFrom, cursorTo);
112 106
 	}
@@ -154,26 +148,26 @@ public class DInputField implements DComponent {
154 148
 		
155 149
 		if (shape != null)
156 150
 			shape.close();
157
-		shape = surface.fillPath(z, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor);
151
+		shape = context.fillPath(0, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor);
158 152
 		text.setPosition(
159 153
 				bounds.x + style.margin.left + style.border.getPaddingLeft(),
160 154
 				bounds.y + style.margin.top + style.border.getPaddingTop() + fontMetrics.getAscent());
161
-		style.border.update(surface, z, bounds);
155
+		style.border.update(context, bounds);
162 156
 	}
163 157
 	
164 158
 	@Override
165 159
 	public void onMouseEnter(DMouseEvent e) {
166
-		surface.getContext().setCursor(DUIContext.Cursor.TEXT);
160
+		context.getUIContext().setCursor(DUIContext.Cursor.TEXT);
167 161
 	}
168 162
 	
169 163
 	@Override
170 164
 	public void onMouseExit(DMouseEvent e) {
171
-		surface.getContext().setCursor(DUIContext.Cursor.NORMAL);
165
+		context.getUIContext().setCursor(DUIContext.Cursor.NORMAL);
172 166
 	}
173 167
 	
174 168
 	@Override
175 169
 	public void onMouseClick(DMouseEvent e) {
176
-		surface.getContext().getWindow().focus(this);
170
+		context.getUIContext().getWindow().focus(this);
177 171
 	}
178 172
 	
179 173
 	@Override
@@ -244,8 +238,8 @@ public class DInputField implements DComponent {
244 238
 	private void handleValueUpdated(String newValue) {
245 239
 		if (text != null)
246 240
 			text.close();
247
-		text = surface.drawText(
248
-				z + 2,
241
+		text = context.drawText(
242
+				2,
249 243
 				style.font,
250 244
 				style.color,
251 245
 				bounds.x + style.margin.left + style.border.getPaddingLeft(),

+ 9
- 16
DrawableGui/src/main/java/org/openzen/drawablegui/DLabel.java View File

@@ -5,14 +5,12 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.draw.DDrawSurface;
9 8
 import org.openzen.drawablegui.draw.DDrawnText;
10 9
 import org.openzen.drawablegui.listeners.ListenerHandle;
11 10
 import org.openzen.drawablegui.live.LiveObject;
12 11
 import org.openzen.drawablegui.live.LiveString;
13 12
 import org.openzen.drawablegui.live.MutableLiveObject;
14 13
 import org.openzen.drawablegui.style.DStyleClass;
15
-import org.openzen.drawablegui.style.DStylePath;
16 14
 
17 15
 /**
18 16
  *
@@ -24,8 +22,7 @@ public class DLabel implements DComponent {
24 22
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
25 23
 	private final ListenerHandle<LiveString.Listener> labelListener;
26 24
 	
27
-	private DDrawSurface surface;
28
-	private int z;
25
+	private DComponentContext context;
29 26
 	private DIRectangle bounds;
30 27
 	private DLabelStyle style;
31 28
 	private DFontMetrics fontMetrics;
@@ -40,19 +37,15 @@ public class DLabel implements DComponent {
40 37
 	}
41 38
 
42 39
 	@Override
43
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
44
-		this.surface = surface;
45
-		this.z = z;
46
-		
47
-		DStylePath path = parent.getChild("label", styleClass);
48
-		style = new DLabelStyle(surface.getStylesheet(path));
49
-		
50
-		fontMetrics = surface.getFontMetrics(style.font);
40
+	public void mount(DComponentContext parent) {
41
+		context = parent.getChildContext("label", styleClass);
42
+		style = context.getStyle(DLabelStyle::new);
43
+		fontMetrics = context.getFontMetrics(style.font);
51 44
 		calculateDimension();
52 45
 		
53 46
 		if (text != null)
54 47
 			text.close();
55
-		text = surface.drawText(z, style.font, style.color, 0, 0, label.getValue());
48
+		text = context.drawText(0, style.font, style.color, 0, 0, label.getValue());
56 49
 	}
57 50
 	
58 51
 	@Override
@@ -81,7 +74,7 @@ public class DLabel implements DComponent {
81 74
 	@Override
82 75
 	public void setBounds(DIRectangle bounds) {
83 76
 		this.bounds = bounds;
84
-		style.border.update(surface, z + 1, bounds);
77
+		style.border.update(context, bounds);
85 78
 		text.setPosition(
86 79
 				bounds.x + style.border.getPaddingLeft(),
87 80
 				bounds.y + style.border.getPaddingTop() + fontMetrics.getAscent());
@@ -98,8 +91,8 @@ public class DLabel implements DComponent {
98 91
 		
99 92
 		if (text != null)
100 93
 			text.close();
101
-		text = surface.drawText(
102
-				z,
94
+		text = context.drawText(
95
+				0,
103 96
 				style.font,
104 97
 				style.color,
105 98
 				bounds.x + style.border.getPaddingLeft(),

+ 11
- 17
DrawableGui/src/main/java/org/openzen/drawablegui/DSimpleTooltipComponent.java View File

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.draw.DDrawSurface;
9 8
 import org.openzen.drawablegui.draw.DDrawnRectangle;
10 9
 import org.openzen.drawablegui.draw.DDrawnText;
11 10
 import org.openzen.drawablegui.listeners.ListenerHandle;
@@ -13,7 +12,6 @@ import org.openzen.drawablegui.live.LiveObject;
13 12
 import org.openzen.drawablegui.live.LiveString;
14 13
 import org.openzen.drawablegui.live.MutableLiveObject;
15 14
 import org.openzen.drawablegui.style.DStyleClass;
16
-import org.openzen.drawablegui.style.DStylePath;
17 15
 
18 16
 /**
19 17
  *
@@ -25,8 +23,7 @@ public class DSimpleTooltipComponent implements DComponent {
25 23
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
26 24
 	private final ListenerHandle<LiveString.Listener> tooltipListener;
27 25
 	
28
-	private DDrawSurface surface;
29
-	private int z;
26
+	private DComponentContext context;
30 27
 	private DIRectangle bounds;
31 28
 	private DFontMetrics fontMetrics;
32 29
 	private DSimpleTooltipStyle style;
@@ -41,7 +38,7 @@ public class DSimpleTooltipComponent implements DComponent {
41 38
 	}
42 39
 	
43 40
 	private void onTooltipChanged(String oldValue, String newValue) {
44
-		if (surface == null || bounds == null)
41
+		if (context == null || bounds == null)
45 42
 			return;
46 43
 		
47 44
 		calculateSize();
@@ -54,8 +51,8 @@ public class DSimpleTooltipComponent implements DComponent {
54 51
 		if (text != null)
55 52
 			text.close();
56 53
 		
57
-		text = surface.drawText(
58
-				z,
54
+		text = context.drawText(
55
+				0,
59 56
 				style.font,
60 57
 				style.textColor,
61 58
 				bounds.x + style.border.getPaddingLeft(),
@@ -66,11 +63,11 @@ public class DSimpleTooltipComponent implements DComponent {
66 63
 	@Override
67 64
 	public void setBounds(DIRectangle bounds) {
68 65
 		this.bounds = bounds;
69
-		style.border.update(surface, z + 1, bounds);
66
+		style.border.update(context, bounds);
70 67
 		
71 68
 		if (background != null)
72 69
 			background.close();
73
-		background = surface.fillRect(z, bounds, style.backgroundColor);
70
+		background = context.fillRect(0, bounds, style.backgroundColor);
74 71
 		text.setPosition(
75 72
 				bounds.x + style.border.getPaddingLeft(),
76 73
 				bounds.y + style.border.getPaddingTop() + fontMetrics.getAscent());
@@ -92,18 +89,15 @@ public class DSimpleTooltipComponent implements DComponent {
92 89
 	}
93 90
 	
94 91
 	@Override
95
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
96
-		this.surface = surface;
97
-		this.z = z;
98
-		
99
-		DStylePath path = parent.getChild("tooltip", styleClass);
100
-		style = new DSimpleTooltipStyle(surface.getStylesheet(path));
101
-		fontMetrics = surface.getFontMetrics(style.font);
92
+	public void mount(DComponentContext parent) {
93
+		context = parent.getChildContext("tooltip", styleClass);
94
+		style = context.getStyle(DSimpleTooltipStyle::new);
95
+		fontMetrics = context.getFontMetrics(style.font);
102 96
 		calculateSize();
103 97
 		
104 98
 		if (text != null)
105 99
 			text.close();
106
-		text = surface.drawText(z + 1, style.font, style.textColor, 0, 0, tooltip.getValue());
100
+		text = parent.drawText(1, style.font, style.textColor, 0, 0, tooltip.getValue());
107 101
 	}
108 102
 	
109 103
 	@Override

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

@@ -26,8 +26,6 @@ public interface DUIContext {
26 26
 	
27 27
 	void setCursor(Cursor cursor);
28 28
 	
29
-	void scrollInView(int x, int y, int width, int height);
30
-	
31 29
 	DTimerHandle setTimer(int millis, Runnable target);
32 30
 	
33 31
 	DClipboard getClipboard();

+ 2
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/border/DBorder.java View File

@@ -6,15 +6,15 @@
6 6
 package org.openzen.drawablegui.border;
7 7
 
8 8
 import java.io.Closeable;
9
+import org.openzen.drawablegui.DComponentContext;
9 10
 import org.openzen.drawablegui.DIRectangle;
10
-import org.openzen.drawablegui.draw.DDrawSurface;
11 11
 
12 12
 /**
13 13
  *
14 14
  * @author Hoofdgebruiker
15 15
  */
16 16
 public interface DBorder extends Closeable {
17
-	public void update(DDrawSurface surface, int z, DIRectangle bounds);
17
+	public void update(DComponentContext context, DIRectangle bounds);
18 18
 	
19 19
 	public int getPaddingLeft();
20 20
 	

+ 3
- 3
DrawableGui/src/main/java/org/openzen/drawablegui/border/DCompositeBorder.java View File

@@ -5,8 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.border;
7 7
 
8
+import org.openzen.drawablegui.DComponentContext;
8 9
 import org.openzen.drawablegui.DIRectangle;
9
-import org.openzen.drawablegui.draw.DDrawSurface;
10 10
 
11 11
 /**
12 12
  *
@@ -20,9 +20,9 @@ public class DCompositeBorder implements DBorder {
20 20
 	}
21 21
 
22 22
 	@Override
23
-	public void update(DDrawSurface surface, int z, DIRectangle bounds) {
23
+	public void update(DComponentContext context, DIRectangle bounds) {
24 24
 		for (DBorder border : borders) {
25
-			border.update(surface, z, bounds);
25
+			border.update(context, bounds);
26 26
 			bounds = new DIRectangle(
27 27
 					bounds.x + border.getPaddingLeft(),
28 28
 					bounds.y + border.getPaddingTop(),

+ 12
- 16
DrawableGui/src/main/java/org/openzen/drawablegui/border/DCustomWindowBorder.java View File

@@ -6,13 +6,13 @@
6 6
 package org.openzen.drawablegui.border;
7 7
 
8 8
 import org.openzen.drawablegui.DComponent;
9
+import org.openzen.drawablegui.DComponentContext;
9 10
 import org.openzen.drawablegui.DSizing;
10 11
 import org.openzen.drawablegui.DMouseEvent;
11 12
 import org.openzen.drawablegui.DPath;
12 13
 import org.openzen.drawablegui.DTransform2D;
13 14
 import org.openzen.drawablegui.DUIWindow;
14 15
 import org.openzen.drawablegui.DIRectangle;
15
-import org.openzen.drawablegui.draw.DDrawSurface;
16 16
 import org.openzen.drawablegui.draw.DDrawnRectangle;
17 17
 import org.openzen.drawablegui.draw.DDrawnShape;
18 18
 import org.openzen.drawablegui.listeners.ListenerHandle;
@@ -20,7 +20,6 @@ import org.openzen.drawablegui.live.ImmutableLiveObject;
20 20
 import org.openzen.drawablegui.live.LiveBool;
21 21
 import org.openzen.drawablegui.live.LiveObject;
22 22
 import org.openzen.drawablegui.style.DStyleClass;
23
-import org.openzen.drawablegui.style.DStylePath;
24 23
 
25 24
 /**
26 25
  *
@@ -31,8 +30,7 @@ public class DCustomWindowBorder implements DComponent {
31 30
 	private final DComponent content;
32 31
 	private final LiveObject<DSizing> sizing = new ImmutableLiveObject<>(DSizing.EMPTY);
33 32
 	
34
-	private DDrawSurface surface;
35
-	private int z;
33
+	private DComponentContext context;
36 34
 	private DCustomWindowBorderStyle style;
37 35
 	private DIRectangle bounds;
38 36
 	
@@ -52,18 +50,16 @@ public class DCustomWindowBorder implements DComponent {
52 50
 	}
53 51
 
54 52
 	@Override
55
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
56
-		this.surface = surface;
57
-		this.z = z;
58
-		content.mount(parent, z + 1, surface);
53
+	public void mount(DComponentContext parent) {
54
+		context = parent.getChildContext("customwindowborder", styleClass);
55
+		content.mount(context);
59 56
 		
60
-		state = surface.getContext().getWindow().getWindowState();
61
-		active = surface.getContext().getWindow().getActive();
57
+		state = parent.getUIContext().getWindow().getWindowState();
58
+		active = parent.getUIContext().getWindow().getActive();
62 59
 		stateListener = state.addListener(this::onStateChanged);
63 60
 		activeListener = active.addListener(this::onActiveChanged);
64 61
 		
65
-		DStylePath path = parent.getChild("customwindowborder", styleClass);
66
-		style = new DCustomWindowBorderStyle(surface.getStylesheet(path));
62
+		style = parent.getStyle(DCustomWindowBorderStyle::new);
67 63
 		
68 64
 		if (bounds != null)
69 65
 			layout();
@@ -113,8 +109,8 @@ public class DCustomWindowBorder implements DComponent {
113 109
 					bounds.height - 2 * style.padding - style.borderWidth);
114 110
 			if (border != null)
115 111
 				border.close();
116
-			border = surface.strokePath(
117
-					z + 1,
112
+			border = context.strokePath(
113
+					1,
118 114
 					path,
119 115
 					DTransform2D.IDENTITY,
120 116
 					active.getValue() ? style.focusedBorderColor : style.inactiveBorderColor,
@@ -135,7 +131,7 @@ public class DCustomWindowBorder implements DComponent {
135 131
 				background.close();
136 132
 				background = null;
137 133
 			}
138
-			shadowedBackground = surface.shadowPath(z, path, DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
134
+			shadowedBackground = context.shadowPath(0, path, DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
139 135
 		} else {
140 136
 			content.setBounds(bounds);
141 137
 			
@@ -148,7 +144,7 @@ public class DCustomWindowBorder implements DComponent {
148 144
 				border = null;
149 145
 			}
150 146
 			if (background == null) {
151
-				background = surface.fillRect(z, bounds, style.backgroundColor);
147
+				background = context.fillRect(0, bounds, style.backgroundColor);
152 148
 			} else {
153 149
 				background.setRectangle(bounds);
154 150
 			}

+ 2
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/border/DEmptyBorder.java View File

@@ -5,8 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.border;
7 7
 
8
+import org.openzen.drawablegui.DComponentContext;
8 9
 import org.openzen.drawablegui.DIRectangle;
9
-import org.openzen.drawablegui.draw.DDrawSurface;
10 10
 import org.openzen.drawablegui.style.DBorderElement;
11 11
 
12 12
 /**
@@ -20,7 +20,7 @@ public class DEmptyBorder implements DBorder {
20 20
 	private DEmptyBorder() {}
21 21
 	
22 22
 	@Override
23
-	public void update(DDrawSurface surface, int z, DIRectangle bounds) {
23
+	public void update(DComponentContext context, DIRectangle bounds) {
24 24
 		
25 25
 	}
26 26
 

+ 3
- 3
DrawableGui/src/main/java/org/openzen/drawablegui/border/DLineBorder.java View File

@@ -5,9 +5,9 @@
5 5
  */
6 6
 package org.openzen.drawablegui.border;
7 7
 
8
+import org.openzen.drawablegui.DComponentContext;
8 9
 import org.openzen.drawablegui.DTransform2D;
9 10
 import org.openzen.drawablegui.DIRectangle;
10
-import org.openzen.drawablegui.draw.DDrawSurface;
11 11
 import org.openzen.drawablegui.draw.DDrawnShape;
12 12
 
13 13
 /**
@@ -26,11 +26,11 @@ public class DLineBorder implements DBorder {
26 26
 	}
27 27
 
28 28
 	@Override
29
-	public void update(DDrawSurface surface, int z, DIRectangle bounds) {
29
+	public void update(DComponentContext context, DIRectangle bounds) {
30 30
 		if (shape != null)
31 31
 			shape.close();
32 32
 		
33
-		shape = surface.strokePath(z, tracer -> {
33
+		shape = context.strokePath(1, tracer -> {
34 34
 				tracer.moveTo(bounds.x, bounds.y);
35 35
 				tracer.lineTo(bounds.x + bounds.width - borderWidth, bounds.y);
36 36
 				tracer.lineTo(bounds.x + bounds.width - borderWidth, bounds.y + bounds.height - borderWidth);

+ 2
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/border/DPaddedBorder.java View File

@@ -5,8 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.border;
7 7
 
8
+import org.openzen.drawablegui.DComponentContext;
8 9
 import org.openzen.drawablegui.DIRectangle;
9
-import org.openzen.drawablegui.draw.DDrawSurface;
10 10
 
11 11
 /**
12 12
  *
@@ -30,7 +30,7 @@ public class DPaddedBorder implements DBorder {
30 30
 	}
31 31
 
32 32
 	@Override
33
-	public void update(DDrawSurface surface, int z, DIRectangle bounds) {
33
+	public void update(DComponentContext context, DIRectangle bounds) {
34 34
 		// nothing to paint
35 35
 	}
36 36
 

+ 6
- 6
DrawableGui/src/main/java/org/openzen/drawablegui/border/DSideBorder.java View File

@@ -5,10 +5,10 @@
5 5
  */
6 6
 package org.openzen.drawablegui.border;
7 7
 
8
+import org.openzen.drawablegui.DComponentContext;
8 9
 import org.openzen.drawablegui.DIRectangle;
9 10
 import org.openzen.drawablegui.DPath;
10 11
 import org.openzen.drawablegui.DTransform2D;
11
-import org.openzen.drawablegui.draw.DDrawSurface;
12 12
 import org.openzen.drawablegui.draw.DDrawnShape;
13 13
 
14 14
 /**
@@ -46,30 +46,30 @@ public class DSideBorder implements DBorder {
46 46
 	}
47 47
 
48 48
 	@Override
49
-	public void update(DDrawSurface surface, int z, DIRectangle bounds) {
49
+	public void update(DComponentContext context, DIRectangle bounds) {
50 50
 		if (leftWidth > 0) {
51 51
 			int x = bounds.x;
52 52
 			if (left != null)
53 53
 				left.close();
54
-			left = surface.strokePath(z, DPath.line(x, bounds.y, x, bounds.y + bounds.height), DTransform2D.IDENTITY, topColor, topWidth);
54
+			left = context.strokePath(1, DPath.line(x, bounds.y, x, bounds.y + bounds.height), DTransform2D.IDENTITY, topColor, topWidth);
55 55
 		}
56 56
 		if (topWidth > 0) {
57 57
 			int y = bounds.y;
58 58
 			if (top != null)
59 59
 				top.close();
60
-			top = surface.strokePath(z, DPath.line(bounds.x, y, bounds.x + bounds.width, y), DTransform2D.IDENTITY, topColor, topWidth);
60
+			top = context.strokePath(1, DPath.line(bounds.x, y, bounds.x + bounds.width, y), DTransform2D.IDENTITY, topColor, topWidth);
61 61
 		}
62 62
 		if (rightWidth > 0) {
63 63
 			int x = bounds.x + bounds.width - rightWidth;
64 64
 			if (right != null)
65 65
 				right.close();
66
-			right = surface.strokePath(z, DPath.line(x, bounds.y, x, bounds.y + bounds.height), DTransform2D.IDENTITY, topColor, topWidth);
66
+			right = context.strokePath(1, DPath.line(x, bounds.y, x, bounds.y + bounds.height), DTransform2D.IDENTITY, topColor, topWidth);
67 67
 		}
68 68
 		if (bottomWidth > 0) {
69 69
 			int y = bounds.y + bounds.height - bottomWidth;
70 70
 			if (bottom != null)
71 71
 				bottom.close();
72
-			bottom = surface.strokePath(z, DPath.line(bounds.x, y, bounds.x + bounds.width, y), DTransform2D.IDENTITY, topColor, topWidth);
72
+			bottom = context.strokePath(1, DPath.line(bounds.x, y, bounds.x + bounds.width, y), DTransform2D.IDENTITY, topColor, topWidth);
73 73
 		}
74 74
 	}
75 75
 

+ 8
- 11
DrawableGui/src/main/java/org/openzen/drawablegui/form/DForm.java View File

@@ -9,15 +9,14 @@ import java.util.function.Consumer;
9 9
 import java.util.function.Predicate;
10 10
 import org.openzen.drawablegui.BaseComponentGroup;
11 11
 import org.openzen.drawablegui.DComponent;
12
+import org.openzen.drawablegui.DComponentContext;
12 13
 import org.openzen.drawablegui.DSizing;
13 14
 import org.openzen.drawablegui.DFontMetrics;
14 15
 import org.openzen.drawablegui.DIRectangle;
15
-import org.openzen.drawablegui.draw.DDrawSurface;
16 16
 import org.openzen.drawablegui.draw.DDrawnText;
17 17
 import org.openzen.drawablegui.live.LiveObject;
18 18
 import org.openzen.drawablegui.live.MutableLiveObject;
19 19
 import org.openzen.drawablegui.style.DStyleClass;
20
-import org.openzen.drawablegui.style.DStylePath;
21 20
 
22 21
 /**
23 22
  *
@@ -28,8 +27,8 @@ public class DForm extends BaseComponentGroup {
28 27
 	private final DStyleClass styleClass;
29 28
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
30 29
 	
30
+	private DComponentContext context;
31 31
 	private DIRectangle bounds;
32
-	private DDrawSurface context;
33 32
 	private DFormStyle style;
34 33
 	private DFontMetrics fontMetrics;
35 34
 	private int maxFieldWidth;
@@ -45,15 +44,13 @@ public class DForm extends BaseComponentGroup {
45 44
 	}
46 45
 
47 46
 	@Override
48
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
49
-		this.context = surface;
50
-		
51
-		DStylePath path = parent.getChild("form", styleClass);
52
-		style = new DFormStyle(surface.getStylesheet(path));
53
-		fontMetrics = surface.getFontMetrics(style.labelFont);
47
+	public void mount(DComponentContext parent) {
48
+		context = parent.getChildContext("form", styleClass);
49
+		style = context.getStyle(DFormStyle::new);
50
+		fontMetrics = context.getFontMetrics(style.labelFont);
54 51
 		
55 52
 		for (DFormComponent component : components)
56
-			component.component.mount(path, z + 1, surface);
53
+			component.component.mount(context);
57 54
 		
58 55
 		int height = style.paddingBottom + style.paddingTop;
59 56
 		int maxLabelWidth = style.minimumLabelSize;
@@ -80,7 +77,7 @@ public class DForm extends BaseComponentGroup {
80 77
 		for (int i = 0; i < labels.length; i++) {
81 78
 			if (labels[i] != null)
82 79
 				labels[i].close();
83
-			labels[i] = surface.drawText(z + 1, style.labelFont, style.labelColor, 0, 0, components[i].label);
80
+			labels[i] = parent.drawText(1, style.labelFont, style.labelColor, 0, 0, components[i].label);
84 81
 		}
85 82
 	}
86 83
 	

+ 11
- 19
DrawableGui/src/main/java/org/openzen/drawablegui/layout/DLinearLayout.java View File

@@ -9,16 +9,15 @@ import java.util.function.Consumer;
9 9
 import java.util.function.Predicate;
10 10
 import org.openzen.drawablegui.BaseComponentGroup;
11 11
 import org.openzen.drawablegui.DComponent;
12
+import org.openzen.drawablegui.DComponentContext;
12 13
 import org.openzen.drawablegui.DIRectangle;
13 14
 import org.openzen.drawablegui.DSizing;
14 15
 import org.openzen.drawablegui.DTransform2D;
15
-import org.openzen.drawablegui.draw.DDrawSurface;
16 16
 import org.openzen.drawablegui.draw.DDrawnShape;
17 17
 import org.openzen.drawablegui.listeners.ListenerHandle;
18 18
 import org.openzen.drawablegui.live.LiveObject;
19 19
 import org.openzen.drawablegui.live.MutableLiveObject;
20 20
 import org.openzen.drawablegui.style.DStyleClass;
21
-import org.openzen.drawablegui.style.DStylePath;
22 21
 
23 22
 /**
24 23
  *
@@ -32,8 +31,7 @@ public class DLinearLayout extends BaseComponentGroup {
32 31
 	private final ListenerHandle<LiveObject.Listener<DSizing>>[] componentSizeListeners;
33 32
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
34 33
 	
35
-	private DDrawSurface surface;
36
-	private int z;
34
+	private DComponentContext context;
37 35
 	private DLinearLayoutStyle style;
38 36
 	private DIRectangle bounds;
39 37
 	private float totalGrow;
@@ -74,15 +72,12 @@ public class DLinearLayout extends BaseComponentGroup {
74 72
 	}
75 73
 
76 74
 	@Override
77
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
78
-		this.surface = surface;
79
-		this.z = z;
80
-		
81
-		DStylePath path = parent.getChild("linearlayout", styleClass);
82
-		style = new DLinearLayoutStyle(surface.getStylesheet(path));
75
+	public void mount(DComponentContext parent) {
76
+		context = parent.getChildContext("linearlayout", styleClass);
77
+		style = context.getStyle(DLinearLayoutStyle::new);
83 78
 		
84 79
 		for (Element element : components)
85
-			element.component.mount(parent, z + 1, surface);
80
+			element.component.mount(context);
86 81
 	}
87 82
 	
88 83
 	@Override
@@ -112,11 +107,11 @@ public class DLinearLayout extends BaseComponentGroup {
112 107
 			return;
113 108
 		
114 109
 		this.bounds = bounds;
115
-		style.border.update(surface, z + 1, bounds);
110
+		style.border.update(context, bounds);
116 111
 		
117 112
 		if (shape != null)
118 113
 			shape.close();
119
-		shape = surface.shadowPath(z, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
114
+		shape = context.shadowPath(0, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
120 115
 		
121 116
 		layout();
122 117
 	}
@@ -149,6 +144,9 @@ public class DLinearLayout extends BaseComponentGroup {
149 144
 	}
150 145
 	
151 146
 	private void layout() {
147
+		if (bounds == null || context == null)
148
+			return;
149
+		
152 150
 		if (orientation == Orientation.HORIZONTAL) {
153 151
 			layoutHorizontal();
154 152
 		} else {
@@ -157,9 +155,6 @@ public class DLinearLayout extends BaseComponentGroup {
157 155
 	}
158 156
 	
159 157
 	private void layoutHorizontal() {
160
-		if (bounds == null || surface == null)
161
-			return;
162
-		
163 158
 		DSizing myPreferences = sizing.getValue();
164 159
 		if (bounds.width < myPreferences.preferredWidth) {
165 160
 			layoutHorizontalShrinked();
@@ -169,9 +164,6 @@ public class DLinearLayout extends BaseComponentGroup {
169 164
 	}
170 165
 	
171 166
 	private void layoutVertical() {
172
-		if (bounds == null || surface == null)
173
-			return;
174
-		
175 167
 		DSizing myPreferences = sizing.getValue();
176 168
 		if (bounds.height < myPreferences.preferredHeight) {
177 169
 			layoutVerticalShrinked();

+ 12
- 17
DrawableGui/src/main/java/org/openzen/drawablegui/layout/DSideLayout.java View File

@@ -12,15 +12,14 @@ import java.util.function.Consumer;
12 12
 import java.util.function.Predicate;
13 13
 import org.openzen.drawablegui.BaseComponentGroup;
14 14
 import org.openzen.drawablegui.DComponent;
15
+import org.openzen.drawablegui.DComponentContext;
15 16
 import org.openzen.drawablegui.DIRectangle;
16 17
 import org.openzen.drawablegui.DSizing;
17
-import org.openzen.drawablegui.draw.DDrawSurface;
18 18
 import org.openzen.drawablegui.draw.DDrawnRectangle;
19 19
 import org.openzen.drawablegui.listeners.ListenerHandle;
20 20
 import org.openzen.drawablegui.live.LiveObject;
21 21
 import org.openzen.drawablegui.live.MutableLiveObject;
22 22
 import org.openzen.drawablegui.style.DStyleClass;
23
-import org.openzen.drawablegui.style.DStylePath;
24 23
 
25 24
 /**
26 25
  *
@@ -33,9 +32,7 @@ public class DSideLayout extends BaseComponentGroup {
33 32
 	private final List<SideComponent> sides = new ArrayList<>();
34 33
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
35 34
 	
36
-	private DStylePath path;
37
-	private DDrawSurface surface;
38
-	private int z;
35
+	private DComponentContext context;
39 36
 	private DSideLayoutStyle style;
40 37
 	private DIRectangle bounds;
41 38
 	
@@ -47,8 +44,8 @@ public class DSideLayout extends BaseComponentGroup {
47 44
 	}
48 45
 	
49 46
 	public void add(Side side, DComponent component) {
50
-		if (surface != null)
51
-			component.mount(path, z + 1, surface);
47
+		if (context != null)
48
+			component.mount(context);
52 49
 		
53 50
 		sides.add(new SideComponent(side, component));
54 51
 	}
@@ -59,26 +56,24 @@ public class DSideLayout extends BaseComponentGroup {
59 56
 		
60 57
 		this.main = component;
61 58
 		
62
-		if (surface != null && bounds != null) {
63
-			main.mount(path, z + 1, surface);
59
+		if (context != null && bounds != null) {
60
+			main.mount(context);
64 61
 			setBounds(bounds);
65 62
 		}
66 63
 	}
67 64
 
68 65
 	@Override
69
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
70
-		this.surface = surface;
71
-		this.z = z;
72
-		this.path = parent.getChild("sidelayout", styleClass);
73
-		style = new DSideLayoutStyle(surface.getStylesheet(path));
66
+	public void mount(DComponentContext parent) {
67
+		context = parent.getChildContext("sidelayout", styleClass);
68
+		style = context.getStyle(DSideLayoutStyle::new);
74 69
 		
75
-		main.mount(path, z + 1, surface);
70
+		main.mount(context);
76 71
 		for (SideComponent side : sides)
77
-			side.component.mount(path, z + 1, surface);
72
+			side.component.mount(context);
78 73
 		
79 74
 		if (background != null)
80 75
 			background.close();
81
-		background = surface.fillRect(z, DIRectangle.EMPTY, style.backgroundColor);
76
+		background = context.fillRect(0, DIRectangle.EMPTY, style.backgroundColor);
82 77
 	}
83 78
 	
84 79
 	@Override

+ 6
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveArrayList.java View File

@@ -52,6 +52,12 @@ public class LiveArrayList<T> implements MutableLiveList<T> {
52 52
 		
53 53
 		remove(index);
54 54
 	}
55
+	
56
+	@Override
57
+	public void clear() {
58
+		for (int i = size() - 1; i >= 0; i--)
59
+			remove(i);
60
+	}
55 61
 
56 62
 	@Override
57 63
 	public int indexOf(T value) {

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

@@ -19,4 +19,6 @@ public interface MutableLiveList<T> extends LiveList<T> {
19 19
 	void remove(int index);
20 20
 	
21 21
 	void remove(T value);
22
+	
23
+	void clear();
22 24
 }

+ 7
- 10
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollBar.java View File

@@ -6,6 +6,7 @@
6 6
 package org.openzen.drawablegui.scroll;
7 7
 
8 8
 import org.openzen.drawablegui.DComponent;
9
+import org.openzen.drawablegui.DComponentContext;
9 10
 import org.openzen.drawablegui.DSizing;
10 11
 import org.openzen.drawablegui.DMouseEvent;
11 12
 import org.openzen.drawablegui.DIRectangle;
@@ -14,12 +15,10 @@ import org.openzen.drawablegui.DTransform2D;
14 15
 import org.openzen.drawablegui.listeners.ListenerHandle;
15 16
 import org.openzen.drawablegui.live.LiveInt;
16 17
 import org.openzen.drawablegui.live.LiveObject;
17
-import org.openzen.drawablegui.draw.DDrawSurface;
18 18
 import org.openzen.drawablegui.draw.DDrawnRectangle;
19 19
 import org.openzen.drawablegui.draw.DDrawnShape;
20 20
 import org.openzen.drawablegui.live.MutableLiveObject;
21 21
 import org.openzen.drawablegui.style.DStyleClass;
22
-import org.openzen.drawablegui.style.DStylePath;
23 22
 
24 23
 /**
25 24
  *
@@ -35,9 +34,8 @@ public class DScrollBar implements DComponent {
35 34
 	private final ListenerHandle<LiveInt.Listener> targetHeightListener;
36 35
 	private final ListenerHandle<LiveInt.Listener> offsetListener;
37 36
 	
38
-	private DDrawSurface surface;
37
+	private DComponentContext context;
39 38
 	private DScrollBarStyle style;
40
-	private int z;
41 39
 	private DIRectangle bounds;
42 40
 	
43 41
 	private int fromY = 0;
@@ -60,13 +58,12 @@ public class DScrollBar implements DComponent {
60 58
 	}
61 59
 
62 60
 	@Override
63
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
64
-		this.surface = surface;
65
-		this.z = z;
66
-		this.style = new DScrollBarStyle(surface.getStylesheet(parent.getChild("scrollbar", styleClass)));
61
+	public void mount(DComponentContext parent) {
62
+		context = parent.getChildContext("scrollbar", styleClass);
63
+		style = context.getStyle(DScrollBarStyle::new);
67 64
 		sizing.setValue(new DSizing(style.width, 0));
68 65
 		
69
-		background = surface.fillRect(z, DIRectangle.EMPTY, style.scrollBarBackgroundColor);
66
+		background = context.fillRect(0, DIRectangle.EMPTY, style.scrollBarBackgroundColor);
70 67
 	}
71 68
 	
72 69
 	@Override
@@ -190,7 +187,7 @@ public class DScrollBar implements DComponent {
190 187
 		
191 188
 		if (bar != null)
192 189
 			bar.close();
193
-		bar = surface.fillPath(z + 1, DPath.rectangle(bounds.x, fromY, bounds.width, toY - fromY), DTransform2D.IDENTITY, style.scrollBarNormalColor);
190
+		bar = context.fillPath(1, DPath.rectangle(bounds.x, fromY, bounds.width, toY - fromY), DTransform2D.IDENTITY, style.scrollBarNormalColor);
194 191
 		updateBarColor();
195 192
 	}
196 193
 	

+ 18
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollContext.java View File

@@ -0,0 +1,18 @@
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.scroll;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public interface DScrollContext {
13
+	void scrollInView(int x, int y, int width, int height);
14
+	
15
+	int getViewportWidth();
16
+	
17
+	int getViewportHeight();
18
+}

+ 33
- 34
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java View File

@@ -5,42 +5,33 @@
5 5
  */
6 6
 package org.openzen.drawablegui.scroll;
7 7
 
8
-import org.openzen.drawablegui.DAnchor;
9
-import org.openzen.drawablegui.DClipboard;
10 8
 import org.openzen.drawablegui.DComponent;
9
+import org.openzen.drawablegui.DComponentContext;
11 10
 import org.openzen.drawablegui.DSizing;
12
-import org.openzen.drawablegui.DFont;
13
-import org.openzen.drawablegui.DFontMetrics;
14 11
 import org.openzen.drawablegui.DIRectangle;
15 12
 import org.openzen.drawablegui.DMouseEvent;
16
-import org.openzen.drawablegui.DTimerHandle;
17 13
 import org.openzen.drawablegui.DTransform2D;
18 14
 import org.openzen.drawablegui.listeners.ListenerHandle;
19 15
 import org.openzen.drawablegui.live.LiveInt;
20 16
 import org.openzen.drawablegui.live.LiveObject;
21 17
 import org.openzen.drawablegui.live.SimpleLiveInt;
22
-import org.openzen.drawablegui.DUIContext;
23
-import org.openzen.drawablegui.DUIWindow;
24
-import org.openzen.drawablegui.draw.DDrawSurface;
25 18
 import org.openzen.drawablegui.draw.DDrawnShape;
26 19
 import org.openzen.drawablegui.draw.DSubSurface;
27 20
 import org.openzen.drawablegui.style.DStyleClass;
28
-import org.openzen.drawablegui.style.DStylePath;
29
-import org.openzen.drawablegui.style.DStyleSheets;
30 21
 
31 22
 /**
32 23
  *
33 24
  * @author Hoofdgebruiker
34 25
  */
35
-public class DScrollPane implements DComponent {
26
+public class DScrollPane implements DComponent, DScrollContext {
36 27
 	private final DStyleClass styleClass;
37 28
 	private final DComponent contents;
38 29
 	private final DScrollBar scrollBar;
39
-	private DDrawSurface surface;
40
-	private DIRectangle bounds;
41 30
 	
31
+	private DComponentContext context;
42 32
 	private DScrollPaneStyle style;
43
-	private int z;
33
+	private DIRectangle bounds;
34
+	
44 35
 	private DDrawnShape shape;
45 36
 	private final LiveInt contentsHeight;
46 37
 	private final LiveInt offsetX;
@@ -80,32 +71,22 @@ public class DScrollPane implements DComponent {
80 71
 			contentsHeight.setValue(newPreferences.preferredHeight);
81 72
 		});
82 73
 	}
83
-	
84
-	@Override
85
-	public void onMounted() {
86
-		contents.onMounted();
87
-	}
88
-	
89
-	@Override
90
-	public void onUnmounted() {
91
-		contents.onUnmounted();
92
-	}
93 74
 
94 75
 	@Override
95
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
96
-		this.surface = surface;
97
-		this.z = z;
76
+	public void mount(DComponentContext parent) {
77
+		context = parent.getChildContext("scrollpane", styleClass);
78
+		style = context.getStyle(DScrollPaneStyle::new);
98 79
 		
99
-		DStylePath path = parent.getChild("scrollpane", styleClass);
100
-		subSurface = surface.createSubSurface(z + 1);
101
-		contents.mount(path, 1, subSurface);
102
-		scrollBar.mount(path, z + 2, surface);
103
-		style = new DScrollPaneStyle(surface.getStylesheet(path));
80
+		subSurface = context.createSubSurface(1);
81
+		DComponentContext newContext = new DComponentContext(this, context.path, 0, subSurface);
82
+		contents.mount(newContext);
83
+		scrollBar.mount(context);
104 84
 	}
105 85
 	
106 86
 	@Override
107 87
 	public void unmount() {
108 88
 		subSurface.close();
89
+		style.border.close();
109 90
 		
110 91
 		contents.unmount();
111 92
 		scrollBar.unmount();
@@ -132,8 +113,8 @@ public class DScrollPane implements DComponent {
132 113
 		
133 114
 		if (shape != null)
134 115
 			shape.close();
135
-		shape = surface.shadowPath(z, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
136
-		style.border.update(surface, z + 1, style.margin.apply(bounds));
116
+		shape = context.shadowPath(0, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
117
+		style.border.update(context, style.margin.apply(bounds));
137 118
 		
138 119
 		int height = Math.max(
139 120
 				bounds.height - style.border.getPaddingHorizontal(),
@@ -268,6 +249,24 @@ public class DScrollPane implements DComponent {
268 249
 	private int toLocalY(int y) {
269 250
 		return y - bounds.y + offsetY.getValue();
270 251
 	}
252
+
253
+	@Override
254
+	public void scrollInView(int x, int y, int width, int height) {
255
+		if (y < offsetY.getValue())
256
+			offsetY.setValue(y);
257
+		if (y + height > offsetY.getValue() + bounds.height)
258
+			offsetY.setValue(y + height - bounds.height);
259
+	}
260
+
261
+	@Override
262
+	public int getViewportWidth() {
263
+		return bounds.width;
264
+	}
265
+
266
+	@Override
267
+	public int getViewportHeight() {
268
+		return bounds.height;
269
+	}
271 270
 	
272 271
 	private class ScrollListener implements LiveInt.Listener {
273 272
 

+ 10
- 10
DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingGraphicsContext.java View File

@@ -16,6 +16,7 @@ import javax.swing.Timer;
16 16
 import org.openzen.drawablegui.DAnchor;
17 17
 import org.openzen.drawablegui.DClipboard;
18 18
 import org.openzen.drawablegui.DComponent;
19
+import org.openzen.drawablegui.DComponentContext;
19 20
 import org.openzen.drawablegui.DSizing;
20 21
 import org.openzen.drawablegui.DPath;
21 22
 import org.openzen.drawablegui.DFont;
@@ -132,11 +133,6 @@ public class SwingGraphicsContext implements DUIContext {
132 133
 		return new SwingFontMetrics(graphics.getFontMetrics((Font) font.cached), graphics);
133 134
 	}
134 135
 
135
-	@Override
136
-	public void scrollInView(int x, int y, int width, int height) {
137
-		// not in a scrollable context
138
-	}
139
-
140 136
 	@Override
141 137
 	public DTimerHandle setTimer(int millis, Runnable target) {
142 138
 		Timer timer = new Timer(millis, e -> target.run());
@@ -165,15 +161,19 @@ public class SwingGraphicsContext implements DUIContext {
165 161
 		
166 162
 		Point rootLocation = swingWindow.swingComponent.getLocationOnScreen();
167 163
 		
168
-		root.mount(DStylePathRoot.INSTANCE, 0, windowContext.surface);
164
+		root.mount(new DComponentContext(null, DStylePathRoot.INSTANCE, 0, windowContext.surface));
169 165
 		DSizing dimension = root.getSizing().getValue();
170
-		int tx = (int)(x + rootLocation.x - anchor.alignX * dimension.preferredWidth);
171
-		int ty = (int)(y + rootLocation.y - anchor.alignY * dimension.preferredHeight);
166
+		//int tx = (int)(x + rootLocation.x - anchor.alignX * dimension.preferredWidth);
167
+		//int ty = (int)(y + rootLocation.y - anchor.alignY * dimension.preferredHeight);
168
+		int dx = (int)(anchor.alignX * dimension.preferredWidth);
169
+		int dy = (int)(anchor.alignY * dimension.preferredHeight);
170
+		int tx = rootLocation.x + x - dx;
171
+		int ty = rootLocation.y + y - dy;
172 172
 		
173 173
 		window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
174 174
 		window.swingComponent.setPreferredSize(new Dimension(dimension.preferredWidth, dimension.preferredHeight));
175
-		window.setLocation(tx, ty);
176 175
 		window.pack();
176
+		window.setLocation(tx, ty);
177 177
 		window.setVisible(true);
178 178
 		return window;
179 179
 	}
@@ -187,7 +187,7 @@ public class SwingGraphicsContext implements DUIContext {
187 187
 		windowContext.graphics = this.graphics; // help a little...
188 188
 		windowContext.setSurface(window.swingComponent.surface);
189 189
 		
190
-		root.mount(DStylePathRoot.INSTANCE, 0, windowContext.surface);
190
+		root.mount(new DComponentContext(null, DStylePathRoot.INSTANCE, 0, windowContext.surface));
191 191
 		DSizing dimension = root.getSizing().getValue();
192 192
 		
193 193
 		Point rootLocation = swingWindow.swingComponent.getLocationOnScreen();

+ 2
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingRoot.java View File

@@ -21,6 +21,7 @@ import java.awt.event.MouseMotionListener;
21 21
 import java.awt.event.MouseWheelEvent;
22 22
 import java.awt.event.MouseWheelListener;
23 23
 import org.openzen.drawablegui.DComponent;
24
+import org.openzen.drawablegui.DComponentContext;
24 25
 import org.openzen.drawablegui.DIRectangle;
25 26
 import org.openzen.drawablegui.DKeyEvent;
26 27
 import static org.openzen.drawablegui.DKeyEvent.KeyCode.*;
@@ -79,7 +80,7 @@ public final class SwingRoot extends Component implements ComponentListener, Mou
79 80
 	public void paint(Graphics g) {
80 81
 		if (firstPaint) {
81 82
 			firstPaint = false;
82
-			component.mount(DStylePathRoot.INSTANCE, 0, surface);
83
+			component.mount(new DComponentContext(null, DStylePathRoot.INSTANCE, 0, surface));
83 84
 			component.setBounds(new DIRectangle(0, 0, getWidth(), getHeight()));
84 85
 		}
85 86
 		

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

@@ -9,6 +9,7 @@ import java.util.ArrayList;
9 9
 import java.util.List;
10 10
 import org.openzen.drawablegui.DColorableIconInstance;
11 11
 import org.openzen.drawablegui.DComponent;
12
+import org.openzen.drawablegui.DComponentContext;
12 13
 import org.openzen.drawablegui.DSizing;
13 14
 import org.openzen.drawablegui.DDrawable;
14 15
 import org.openzen.drawablegui.DFontMetrics;
@@ -26,7 +27,6 @@ import org.openzen.drawablegui.live.LiveList;
26 27
 import org.openzen.drawablegui.live.LiveObject;
27 28
 import org.openzen.drawablegui.live.MutableLiveObject;
28 29
 import org.openzen.drawablegui.style.DStyleClass;
29
-import org.openzen.drawablegui.style.DStylePath;
30 30
 
31 31
 /**
32 32
  *
@@ -35,8 +35,9 @@ import org.openzen.drawablegui.style.DStylePath;
35 35
 public class DTreeView<N extends DTreeNode<N>> implements DComponent {
36 36
 	private final DStyleClass styleClass;
37 37
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
38
+	
39
+	private DComponentContext context;
38 40
 	private DIRectangle bounds = DIRectangle.EMPTY;
39
-	private int z;
40 41
 	
41 42
 	private int selectedRow = -1;
42 43
 	private N selectedNode = null;
@@ -47,7 +48,6 @@ public class DTreeView<N extends DTreeNode<N>> implements DComponent {
47 48
 	private final DDrawable nodeOpenedIcon;
48 49
 	private final DDrawable nodeClosedIcon;
49 50
 	
50
-	private DDrawSurface surface;
51 51
 	private final N root;
52 52
 	private final boolean showRoot;
53 53
 	private final List<Row> rows = new ArrayList<>();
@@ -72,13 +72,13 @@ public class DTreeView<N extends DTreeNode<N>> implements DComponent {
72 72
 	}
73 73
 
74 74
 	@Override
75
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
76
-		this.surface = surface;
77
-		style = new DTreeViewStyle(surface.getStylesheet(parent.getChild("tree", styleClass)));
78
-		fontMetrics = surface.getFontMetrics(style.font);
75
+	public void mount(DComponentContext parent) {
76
+		context = parent.getChildContext("tree", styleClass);
77
+		style = context.getStyle(DTreeViewStyle::new);
78
+		fontMetrics = context.getFontMetrics(style.font);
79 79
 		
80
-		background = surface.fillRect(z, DIRectangle.EMPTY, style.backgroundColor);
81
-		selectedBackground = surface.fillRect(z + 1, DIRectangle.EMPTY, 0);
80
+		background = context.fillRect(0, DIRectangle.EMPTY, style.backgroundColor);
81
+		selectedBackground = context.fillRect(1, DIRectangle.EMPTY, 0);
82 82
 		
83 83
 		updateLayout();
84 84
 	}
@@ -261,21 +261,21 @@ public class DTreeView<N extends DTreeNode<N>> implements DComponent {
261 261
 			
262 262
 			icon = node.isCollapsed().getValue() ? nodeClosedIcon : nodeOpenedIcon;
263 263
 			nodeIcon = new DColorableIconInstance(
264
-					surface,
265
-					z + 2,
264
+					context.surface,
265
+					context.z + 2,
266 266
 					node.getIcon(),
267 267
 					DTransform2D.translate(baseX + icon.getNominalWidth() + style.iconTextSpacing, baseY + fontMetrics.getAscent() + fontMetrics.getDescent() - icon.getNominalHeight()),
268 268
 					node == selectedNode ? style.selectedNodeTextColor : style.nodeTextColor);
269 269
 			
270 270
 			if (!node.isLeaf())
271 271
 				collapseIcon = new DDrawableInstance(
272
-						surface, 
273
-						z + 2,
272
+						context.surface, 
273
+						context.z + 2,
274 274
 						icon,
275 275
 						DTransform2D.translate(baseX, baseY + fontMetrics.getAscent() + fontMetrics.getDescent() - icon.getNominalHeight()));
276 276
 			
277
-			text = surface.drawText(
278
-					z + 2,
277
+			text = context.drawText(
278
+					2,
279 279
 					style.font,
280 280
 					node == selectedNode ? style.selectedNodeTextColor : style.nodeTextColor,
281 281
 					baseX + style.iconTextSpacing + icon.getNominalWidth() + style.iconTextSpacing + node.getIcon().getNominalWidth(),

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

@@ -66,7 +66,12 @@ public class LocalTarget implements IDETarget {
66 66
 	
67 67
 	private ZenCodeCompiler buildInternal(Consumer<OutputLine> output) {
68 68
 		CompilationUnit compilationUnit = new CompilationUnit();
69
-		ModuleLoader moduleLoader = new ModuleLoader(compilationUnit, exception -> output.accept(new OutputLine(new ErrorOutputSpan(exception.getMessage()))));
69
+		ModuleLoader moduleLoader = new ModuleLoader(compilationUnit, exception -> {
70
+			String[] lines = Strings.split(exception.getMessage(), '\n');
71
+			for (String line : lines) {
72
+				output.accept(new OutputLine(new ErrorOutputSpan(line)));
73
+			}
74
+		});
70 75
 		moduleLoader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
71 76
 		Set<String> compiledModules = new HashSet<>();
72 77
 		

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

@@ -61,6 +61,7 @@ public class IDEWindow {
61 61
 			
62 62
 		}));
63 63
 		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, BuildIcon.BLUE, new ImmutableLiveString("Build"), e -> {
64
+			output.clear();
64 65
 			for (IDETarget target : host.getTargets()) {
65 66
 				if (target.canBuild())
66 67
 					target.build(line -> output.add(line));

+ 1
- 1
IDE/src/main/java/org/openzen/zenscript/ide/ui/dialog/CreateSourceFileDialog.java View File

@@ -80,7 +80,7 @@ public class CreateSourceFileDialog {
80 80
 	
81 81
 	public void open(DUIWindow parent) {
82 82
 		DIRectangle rectangle = parent.getWindowBounds().getValue();
83
-		window = parent.getContext().openDialog(rectangle.getCenterX(), rectangle.getCenterY(), DAnchor.MIDDLE_CENTER, "Create source file", root);
83
+		window = parent.getContext().openDialog(rectangle.width / 2, rectangle.height / 2, DAnchor.MIDDLE_CENTER, "Create source file", root);
84 84
 		window.focus(input);
85 85
 	}
86 86
 	

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

@@ -7,6 +7,7 @@ package org.openzen.zenscript.ide.ui.view;
7 7
 
8 8
 import java.util.function.Consumer;
9 9
 import org.openzen.drawablegui.DComponent;
10
+import org.openzen.drawablegui.DComponentContext;
10 11
 import org.openzen.drawablegui.DSizing;
11 12
 import org.openzen.drawablegui.DDrawable;
12 13
 import org.openzen.drawablegui.DDrawableInstance;
@@ -15,7 +16,6 @@ import org.openzen.drawablegui.DPath;
15 16
 import org.openzen.drawablegui.DTransform2D;
16 17
 import org.openzen.drawablegui.DIRectangle;
17 18
 import org.openzen.drawablegui.DSimpleTooltip;
18
-import org.openzen.drawablegui.draw.DDrawSurface;
19 19
 import org.openzen.drawablegui.draw.DDrawnShape;
20 20
 import org.openzen.drawablegui.listeners.ListenerHandle;
21 21
 import org.openzen.drawablegui.live.ImmutableLiveBool;
@@ -25,7 +25,6 @@ import org.openzen.drawablegui.live.LiveString;
25 25
 import org.openzen.drawablegui.live.MutableLiveObject;
26 26
 import org.openzen.drawablegui.style.DShadow;
27 27
 import org.openzen.drawablegui.style.DStyleClass;
28
-import org.openzen.drawablegui.style.DStylePath;
29 28
 
30 29
 /**
31 30
  *
@@ -39,12 +38,11 @@ public class IconButtonControl implements DComponent {
39 38
 	private final LiveBool disabled;
40 39
 	private final ListenerHandle<LiveBool.Listener> disabledListener;
41 40
 	private final DSimpleTooltip tooltip;
41
+	private final MutableLiveObject<DSizing> sizing = DSizing.create();
42 42
 	
43
-	private DDrawSurface surface;
44
-	private int z;
43
+	private DComponentContext context;
45 44
 	private IconButtonControlStyle style;
46 45
 	private DIRectangle bounds;
47
-	private final MutableLiveObject<DSizing> preferences = DSizing.create();
48 46
 	private boolean hover;
49 47
 	private boolean press;
50 48
 	
@@ -67,20 +65,17 @@ public class IconButtonControl implements DComponent {
67 65
 	}
68 66
 
69 67
 	@Override
70
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
71
-		this.surface = surface;
72
-		this.z = z;
68
+	public void mount(DComponentContext parent) {
69
+		context = parent.getChildContext("iconbutton", styleClass);
70
+		style = context.getStyle(IconButtonControlStyle::new);
73 71
 		
74
-		tooltip.setContext(surface.getContext());
72
+		tooltip.setContext(context.getUIContext());
75 73
 		
76
-		DStylePath path = parent.getChild("iconbutton", styleClass);
77
-		style = new IconButtonControlStyle(surface.getStylesheet(path));
78
-		
79
-		int iconWidth = (int)(icon.getNominalWidth() * surface.getScale() + 0.5f);
80
-		int iconHeight = (int)(icon.getNominalWidth() * surface.getScale() + 0.5f);
74
+		int iconWidth = (int)(icon.getNominalWidth() * context.getScale() + 0.5f);
75
+		int iconHeight = (int)(icon.getNominalWidth() * context.getScale() + 0.5f);
81 76
 		int width = iconWidth + 2 * style.padding + 2 * style.margin;
82 77
 		int height = iconHeight + 2 * style.padding + 2 * style.margin;
83
-		preferences.setValue(new DSizing(width, height));
78
+		sizing.setValue(new DSizing(width, height));
84 79
 		
85 80
 		if (bounds != null)
86 81
 			setBounds(bounds);
@@ -96,7 +91,7 @@ public class IconButtonControl implements DComponent {
96 91
 
97 92
 	@Override
98 93
 	public LiveObject<DSizing> getSizing() {
99
-		return preferences;
94
+		return sizing;
100 95
 	}
101 96
 
102 97
 	@Override
@@ -117,7 +112,7 @@ public class IconButtonControl implements DComponent {
117 112
 			shape.close();
118 113
 		
119 114
 		shadow = getShadow();
120
-		shape = surface.shadowPath(z, DPath.roundedRectangle(
115
+		shape = context.shadowPath(0, DPath.roundedRectangle(
121 116
 				bounds.x + style.margin,
122 117
 				bounds.y + style.margin,
123 118
 				bounds.width - 2 * style.margin,
@@ -176,10 +171,10 @@ public class IconButtonControl implements DComponent {
176 171
 		if (drawnIcon != null)
177 172
 			drawnIcon.close();
178 173
 		
179
-		drawnIcon = new DDrawableInstance(surface, z + 1, icon, DTransform2D.scaleAndTranslate(
180
-				bounds.x + (bounds.width - icon.getNominalWidth() * surface.getScale()) / 2,
181
-				bounds.y + (bounds.height - icon.getNominalHeight() * surface.getScale()) / 2,
182
-				surface.getScale()));
174
+		drawnIcon = new DDrawableInstance(context.surface, context.z + 1, icon, DTransform2D.scaleAndTranslate(
175
+				bounds.x + (bounds.width - icon.getNominalWidth() * context.getScale()) / 2,
176
+				bounds.y + (bounds.height - icon.getNominalHeight() * context.getScale()) / 2,
177
+				context.getScale()));
183 178
 	}
184 179
 	
185 180
 	private void update() {
@@ -189,7 +184,7 @@ public class IconButtonControl implements DComponent {
189 184
 				shape.close();
190 185
 			
191 186
 			shadow = newShadow;
192
-			shape = surface.shadowPath(z, DPath.roundedRectangle(
187
+			shape = context.shadowPath(0, DPath.roundedRectangle(
193 188
 					bounds.x + style.margin,
194 189
 					bounds.y + style.margin,
195 190
 					bounds.width - 2 * style.margin,

+ 9
- 14
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/StatusBarView.java View File

@@ -6,6 +6,7 @@
6 6
 package org.openzen.zenscript.ide.ui.view;
7 7
 
8 8
 import org.openzen.drawablegui.DComponent;
9
+import org.openzen.drawablegui.DComponentContext;
9 10
 import org.openzen.drawablegui.DSizing;
10 11
 import org.openzen.drawablegui.DFontMetrics;
11 12
 import org.openzen.drawablegui.DIRectangle;
@@ -13,12 +14,10 @@ import org.openzen.drawablegui.DPath;
13 14
 import org.openzen.drawablegui.DTransform2D;
14 15
 import org.openzen.drawablegui.live.LiveObject;
15 16
 import org.openzen.drawablegui.live.SimpleLiveObject;
16
-import org.openzen.drawablegui.draw.DDrawSurface;
17 17
 import org.openzen.drawablegui.draw.DDrawnShape;
18 18
 import org.openzen.drawablegui.draw.DDrawnText;
19 19
 import org.openzen.drawablegui.live.LiveString;
20 20
 import org.openzen.drawablegui.style.DStyleClass;
21
-import org.openzen.drawablegui.style.DStylePath;
22 21
 
23 22
 /**
24 23
  *
@@ -29,11 +28,10 @@ public class StatusBarView implements DComponent {
29 28
 	
30 29
 	private final DStyleClass styleClass;
31 30
 	private final LiveString content;
32
-	private DIRectangle bounds;
33
-	private DDrawSurface surface;
34
-	private int z;
31
+	private DComponentContext context;
35 32
 	private StatusBarStyle style;
36 33
 	private DFontMetrics fontMetrics;
34
+	private DIRectangle bounds;
37 35
 
38 36
 	private DDrawnShape shape;
39 37
 	private DDrawnText text;
@@ -44,16 +42,13 @@ public class StatusBarView implements DComponent {
44 42
 	}
45 43
 	
46 44
 	@Override
47
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
48
-		this.surface = surface;
49
-		this.z = z;
50
-		
51
-		DStylePath path = parent.getChild("StatusBar", styleClass);
52
-		style = new StatusBarStyle(surface.getStylesheet(path));
53
-		fontMetrics = surface.getFontMetrics(style.font);
45
+	public void mount(DComponentContext parent) {
46
+		context = parent.getChildContext("statusbar", styleClass);
47
+		style = context.getStyle(StatusBarStyle::new);
48
+		fontMetrics = context.getFontMetrics(style.font);
54 49
 		
55 50
 		dimensionPreferences.setValue(new DSizing(0, style.paddingTop + fontMetrics.getAscent() + fontMetrics.getDescent() + style.paddingBottom));
56
-		text = surface.drawText(z + 1, style.font, style.textColor, 0, 0, content.getValue());
51
+		text = context.drawText(1, style.font, style.textColor, 0, 0, content.getValue());
57 52
 	}
58 53
 	
59 54
 	@Override
@@ -85,7 +80,7 @@ public class StatusBarView implements DComponent {
85 80
 		
86 81
 		if (shape != null)
87 82
 			shape.close();
88
-		shape = surface.shadowPath(z, DPath.rectangle(bounds.x, bounds.y, bounds.width, bounds.height), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
83
+		shape = context.shadowPath(0, DPath.rectangle(bounds.x, bounds.y, bounds.width, bounds.height), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
89 84
 		text.setPosition(bounds.x + style.paddingLeft, bounds.y + style.paddingTop + fontMetrics.getAscent());
90 85
 	}
91 86
 

+ 14
- 22
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedView.java View File

@@ -11,6 +11,7 @@ import java.util.function.Consumer;
11 11
 import java.util.function.Predicate;
12 12
 import org.openzen.drawablegui.BaseComponentGroup;
13 13
 import org.openzen.drawablegui.DComponent;
14
+import org.openzen.drawablegui.DComponentContext;
14 15
 import org.openzen.drawablegui.DSizing;
15 16
 import org.openzen.drawablegui.DFontMetrics;
16 17
 import org.openzen.drawablegui.DIRectangle;
@@ -38,18 +39,16 @@ public class TabbedView extends BaseComponentGroup {
38 39
 	
39 40
 	private final Map<TabbedViewTab, ListenerHandle<LiveObject.Listener<DSizing>>> tabSizeListeners = new HashMap<>();
40 41
 	
41
-	private DDrawSurface surface;
42
-	private DStylePath path;
43
-	private DIRectangle bounds;
42
+	private DComponentContext context;
44 43
 	private TabbedViewStyle style;
44
+	private DIRectangle bounds;
45 45
 	private int totalTabHeight;
46 46
 	private DFontMetrics fontMetrics;
47
-	private int z;
48 47
 
49 48
 	private final LiveList<TabbedViewTab> tabComponents = new LiveMappedList<>(tabs, tab -> {
50
-		TabbedViewTab result = new TabbedViewTab(this, currentTab, tab);
51
-		if (surface != null)
52
-			result.mount(path, z + 2, surface);
49
+		TabbedViewTab result = new TabbedViewTab(DStyleClass.EMPTY, this, currentTab, tab);
50
+		if (context != null)
51
+			result.mount(context);
53 52
 		
54 53
 		tabSizeListeners.put(result, result.getSizing().addListener((oldSize, newSize) -> layoutTabs()));
55 54
 		return result;
@@ -60,14 +59,10 @@ public class TabbedView extends BaseComponentGroup {
60 59
 		tabs.addListener(new TabListListener());
61 60
 		
62 61
 		currentTab.addListener((oldValue, newValue) -> {
63
-			if (oldValue != null) {
64
-				oldValue.content.onUnmounted();
62
+			if (oldValue != null)
65 63
 				oldValue.content.unmount();
66
-			}
67
-			if (newValue != null) {
68
-				newValue.content.onMounted();
69
-				newValue.content.mount(path, z + 1, surface);
70
-			}
64
+			if (newValue != null)
65
+				newValue.content.mount(context);
71 66
 			
72 67
 			if (newValue != null && bounds != null) {
73 68
 				DIRectangle contentBounds = new DIRectangle(
@@ -81,13 +76,10 @@ public class TabbedView extends BaseComponentGroup {
81 76
 	}
82 77
 	
83 78
 	@Override
84
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
85
-		this.surface = surface;
86
-		this.z = z;
87
-		
88
-		path = parent.getChild("tabbedView", styleClass);
89
-		style = new TabbedViewStyle(surface.getStylesheet(path));
90
-		fontMetrics = surface.getFontMetrics(style.tabFont);
79
+	public void mount(DComponentContext parent) {
80
+		context = parent.getChildContext("tabbedview", styleClass);
81
+		style = context.getStyle(TabbedViewStyle::new);
82
+		fontMetrics = context.getFontMetrics(style.tabFont);
91 83
 		totalTabHeight = style.tabBorder.getPaddingVertical() + fontMetrics.getAscent() + fontMetrics.getDescent();
92 84
 		
93 85
 		for (TabbedViewComponent tab : tabs)
@@ -146,7 +138,7 @@ public class TabbedView extends BaseComponentGroup {
146 138
 	}
147 139
 	
148 140
 	private void prepare(TabbedViewComponent tab) {
149
-		tab.content.mount(path, z + 1, surface);
141
+		tab.content.mount(context);
150 142
 	}
151 143
 	
152 144
 	private void layoutTabs() {

+ 15
- 18
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTab.java View File

@@ -6,13 +6,13 @@
6 6
 package org.openzen.zenscript.ide.ui.view;
7 7
 
8 8
 import org.openzen.drawablegui.DComponent;
9
+import org.openzen.drawablegui.DComponentContext;
9 10
 import org.openzen.drawablegui.DSizing;
10 11
 import org.openzen.drawablegui.DFontMetrics;
11 12
 import org.openzen.drawablegui.DIRectangle;
12 13
 import org.openzen.drawablegui.DMouseEvent;
13 14
 import org.openzen.drawablegui.DPath;
14 15
 import org.openzen.drawablegui.DTransform2D;
15
-import org.openzen.drawablegui.draw.DDrawSurface;
16 16
 import org.openzen.drawablegui.draw.DDrawnShape;
17 17
 import org.openzen.drawablegui.draw.DDrawnText;
18 18
 import org.openzen.drawablegui.listeners.ListenerHandle;
@@ -21,7 +21,6 @@ import org.openzen.drawablegui.live.LiveObject;
21 21
 import org.openzen.drawablegui.live.LiveString;
22 22
 import org.openzen.drawablegui.live.MutableLiveObject;
23 23
 import org.openzen.drawablegui.style.DStyleClass;
24
-import org.openzen.drawablegui.style.DStylePath;
25 24
 
26 25
 /**
27 26
  *
@@ -32,11 +31,11 @@ public class TabbedViewTab implements DComponent {
32 31
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
33 32
 	private final MutableLiveObject<TabbedViewComponent> currentTab;
34 33
 	
34
+	private final DStyleClass styleClass;
35 35
 	private final TabbedView parent;
36 36
 	public final TabbedViewTabClose closeButton;
37 37
 	
38
-	private DDrawSurface surface;
39
-	private int z;
38
+	private DComponentContext context;
40 39
 	private TabbedViewTabStyle style;
41 40
 	private DFontMetrics fontMetrics;
42 41
 	private int textWidth;
@@ -53,7 +52,8 @@ public class TabbedViewTab implements DComponent {
53 52
 	private DDrawnShape updated;
54 53
 	private DDrawnText text;
55 54
 	
56
-	public TabbedViewTab(TabbedView parent, MutableLiveObject<TabbedViewComponent> currentTab, TabbedViewComponent tab) {
55
+	public TabbedViewTab(DStyleClass styleClass, TabbedView parent, MutableLiveObject<TabbedViewComponent> currentTab, TabbedViewComponent tab) {
56
+		this.styleClass = styleClass;
57 57
 		this.parent = parent;
58 58
 		this.currentTab = currentTab;
59 59
 		this.tab = tab;
@@ -69,16 +69,13 @@ public class TabbedViewTab implements DComponent {
69 69
 	}
70 70
 
71 71
 	@Override
72
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
73
-		this.surface = surface;
74
-		this.z = z;
72
+	public void mount(DComponentContext parent) {
73
+		context = parent.getChildContext("tab", styleClass);
74
+		style = context.getStyle(TabbedViewTabStyle::new);
75
+		fontMetrics = context.getFontMetrics(style.tabFont);
76
+		closeButton.mount(context);
75 77
 		
76
-		DStylePath path = parent.getChild("tab", DStyleClass.EMPTY);
77
-		style = new TabbedViewTabStyle(surface.getStylesheet(path));
78
-		fontMetrics = surface.getFontMetrics(style.tabFont);
79
-		closeButton.mount(path, z + 1, surface);
80
-		
81
-		text = surface.drawText(z + 1, style.tabFont, style.tabFontColor, 0, 0, tab.title.getValue());
78
+		text = context.drawText(1, style.tabFont, style.tabFontColor, 0, 0, tab.title.getValue());
82 79
 		calculateSizing();
83 80
 	}
84 81
 	
@@ -130,7 +127,7 @@ public class TabbedViewTab implements DComponent {
130 127
 		this.bounds = bounds;
131 128
 		
132 129
 		DSizing close = closeButton.getSizing().getValue();
133
-		style.border.update(surface, z + 1, style.margin.apply(bounds));
130
+		style.border.update(context, style.margin.apply(bounds));
134 131
 		
135 132
 		closeButton.setBounds(new DIRectangle(
136 133
 				bounds.x + bounds.width - close.preferredWidth - style.border.getPaddingRight(),
@@ -140,7 +137,7 @@ public class TabbedViewTab implements DComponent {
140 137
 		
141 138
 		if (shape != null)
142 139
 			shape.close();
143
-		shape = surface.shadowPath(z, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
140
+		shape = context.shadowPath(0, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
144 141
 		text.setPosition(
145 142
 				bounds.x + style.margin.left + style.border.getPaddingLeft(),
146 143
 				bounds.y + style.margin.top + style.border.getPaddingTop() + fontMetrics.getAscent());
@@ -148,8 +145,8 @@ public class TabbedViewTab implements DComponent {
148 145
 		if (tab.updated.getValue()) {
149 146
 			if (updated != null)
150 147
 				updated.close();
151
-			updated = surface.fillPath(
152
-					z + 1,
148
+			updated = context.fillPath(
149
+					1,
153 150
 					DPath.circle(
154 151
 						bounds.x + bounds.width - style.margin.right - style.border.getPaddingRight() - closeButton.getBounds().width - style.closeIconPadding - style.updatedDiameter / 2,
155 152
 						bounds.y + style.margin.top + style.border.getPaddingTop() + ((bounds.height - style.margin.getVertical() - style.border.getPaddingVertical()) / 2), style.updatedDiameter / 2),

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

@@ -8,16 +8,15 @@ package org.openzen.zenscript.ide.ui.view;
8 8
 import org.openzen.drawablegui.DColorableIcon;
9 9
 import org.openzen.drawablegui.DColorableIconInstance;
10 10
 import org.openzen.drawablegui.DComponent;
11
+import org.openzen.drawablegui.DComponentContext;
11 12
 import org.openzen.drawablegui.DSizing;
12 13
 import org.openzen.drawablegui.DIRectangle;
13 14
 import org.openzen.drawablegui.DMouseEvent;
14 15
 import org.openzen.drawablegui.DTransform2D;
15
-import org.openzen.drawablegui.draw.DDrawSurface;
16 16
 import org.openzen.drawablegui.draw.DDrawnRectangle;
17 17
 import org.openzen.drawablegui.live.LiveObject;
18 18
 import org.openzen.drawablegui.live.MutableLiveObject;
19 19
 import org.openzen.drawablegui.style.DStyleClass;
20
-import org.openzen.drawablegui.style.DStylePath;
21 20
 import org.openzen.zenscript.ide.ui.icons.ScalableCloseIcon;
22 21
 
23 22
 /**
@@ -28,8 +27,7 @@ public class TabbedViewTabClose implements DComponent {
28 27
 	private final TabbedViewTab tab;
29 28
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
30 29
 	
31
-	private DDrawSurface surface;
32
-	private int z;
30
+	private DComponentContext context;
33 31
 	private DIRectangle bounds;
34 32
 	private TabbedViewTabCloseStyle style;
35 33
 	private DColorableIcon icon;
@@ -45,21 +43,18 @@ public class TabbedViewTabClose implements DComponent {
45 43
 	}
46 44
 
47 45
 	@Override
48
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
49
-		this.surface = surface;
50
-		this.z = z;
51
-		
52
-		DStylePath path = parent.getChild("tabClose", DStyleClass.EMPTY);
53
-		style = new TabbedViewTabCloseStyle(surface.getStylesheet(path));
46
+	public void mount(DComponentContext parent) {
47
+		context = parent.getChildContext("tabclose", DStyleClass.EMPTY);
48
+		style = context.getStyle(TabbedViewTabCloseStyle::new);
54 49
 		sizing.setValue(new DSizing(style.size, style.size));
55 50
 		icon = new ScalableCloseIcon(style.size / 24);
56 51
 		
57 52
 		if (background != null)
58 53
 			background.close();
59
-		background = surface.fillRect(z, DIRectangle.EMPTY, hover ? 0xFFE81123 : 0);
54
+		background = context.fillRect(9, DIRectangle.EMPTY, hover ? 0xFFE81123 : 0);
60 55
 		if (drawnIcon != null)
61 56
 			drawnIcon.close();
62
-		drawnIcon = new DColorableIconInstance(surface, z + 1, icon, DTransform2D.IDENTITY, 0xFF000000);
57
+		drawnIcon = new DColorableIconInstance(context.surface, context.z + 1, icon, DTransform2D.IDENTITY, 0xFF000000);
63 58
 	}
64 59
 	
65 60
 	@Override
@@ -93,7 +88,7 @@ public class TabbedViewTabClose implements DComponent {
93 88
 		
94 89
 		if (drawnIcon != null)
95 90
 			drawnIcon.close();
96
-		drawnIcon = new DColorableIconInstance(surface, z + 1, icon, DTransform2D.translate(
91
+		drawnIcon = new DColorableIconInstance(context.surface, context.z + 1, icon, DTransform2D.translate(
97 92
 				bounds.x + (bounds.width - icon.getNominalWidth()) / 2,
98 93
 				bounds.y + (bounds.height - icon.getNominalHeight()) / 2), 0xFF000000);
99 94
 	}

+ 16
- 19
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarSelectorButton.java View File

@@ -7,6 +7,7 @@ package org.openzen.zenscript.ide.ui.view.aspectbar;
7 7
 
8 8
 import java.util.function.Consumer;
9 9
 import org.openzen.drawablegui.DComponent;
10
+import org.openzen.drawablegui.DComponentContext;
10 11
 import org.openzen.drawablegui.DSizing;
11 12
 import org.openzen.drawablegui.DDrawable;
12 13
 import org.openzen.drawablegui.DDrawableInstance;
@@ -15,7 +16,6 @@ import org.openzen.drawablegui.DPath;
15 16
 import org.openzen.drawablegui.DTransform2D;
16 17
 import org.openzen.drawablegui.DIRectangle;
17 18
 import org.openzen.drawablegui.DSimpleTooltip;
18
-import org.openzen.drawablegui.draw.DDrawSurface;
19 19
 import org.openzen.drawablegui.draw.DDrawnShape;
20 20
 import org.openzen.drawablegui.listeners.ListenerHandle;
21 21
 import org.openzen.drawablegui.live.ImmutableLiveString;
@@ -24,7 +24,6 @@ import org.openzen.drawablegui.live.LiveObject;
24 24
 import org.openzen.drawablegui.live.MutableLiveObject;
25 25
 import org.openzen.drawablegui.style.DShadow;
26 26
 import org.openzen.drawablegui.style.DStyleClass;
27
-import org.openzen.drawablegui.style.DStylePath;
28 27
 
29 28
 /**
30 29
  *
@@ -37,8 +36,8 @@ public class AspectBarSelectorButton implements DComponent {
37 36
 	private final DDrawable icon;
38 37
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
39 38
 	private final Consumer<DMouseEvent> onClick;
40
-	private DDrawSurface surface;
41
-	private int z;
39
+	
40
+	private DComponentContext context;
42 41
 	private AspectBarSelectorButtonStyle style;
43 42
 	private DIRectangle bounds = DIRectangle.EMPTY;
44 43
 	private DDrawnShape shape;
@@ -62,14 +61,12 @@ public class AspectBarSelectorButton implements DComponent {
62 61
 	}
63 62
 
64 63
 	@Override
65
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
66
-		this.surface = surface;
67
-		this.z = z;
68
-		DStylePath path = parent.getChild("selectorbutton", styleClass);
69
-		style = new AspectBarSelectorButtonStyle(surface.getStylesheet(path));
64
+	public void mount(DComponentContext parent) {
65
+		context = parent.getChildContext("selectorbutton", styleClass);
66
+		style = context.getStyle(AspectBarSelectorButtonStyle::new);
70 67
 		sizing.setValue(new DSizing(style.width, style.height));
71 68
 		
72
-		tooltip.setContext(surface.getContext());
69
+		tooltip.setContext(context.getUIContext());
73 70
 	}
74 71
 
75 72
 	@Override
@@ -95,8 +92,8 @@ public class AspectBarSelectorButton implements DComponent {
95 92
 			shape.close();
96 93
 		
97 94
 		shadow = getShadow();
98
-		shape = surface.shadowPath(
99
-				z,
95
+		shape = context.shadowPath(
96
+				0,
100 97
 				DPath.roundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, style.roundingRadius),
101 98
 				DTransform2D.IDENTITY,
102 99
 				getColor(),
@@ -104,10 +101,10 @@ public class AspectBarSelectorButton implements DComponent {
104 101
 		
105 102
 		if (iconInstance != null)
106 103
 			iconInstance.close();
107
-		iconInstance = new DDrawableInstance(surface, z + 1, icon, DTransform2D.scaleAndTranslate(
108
-				bounds.x + (style.width - icon.getNominalWidth() * surface.getScale()) / 2,
109
-				bounds.y + (style.height - icon.getNominalHeight() * surface.getScale()) / 2,
110
-				surface.getScale()));
104
+		iconInstance = new DDrawableInstance(context.surface, context.z + 1, icon, DTransform2D.scaleAndTranslate(
105
+				bounds.x + (style.width - icon.getNominalWidth() * context.getScale()) / 2,
106
+				bounds.y + (style.height - icon.getNominalHeight() * context.getScale()) / 2,
107
+				context.getScale()));
111 108
 	}
112 109
 	
113 110
 	@Override
@@ -164,7 +161,7 @@ public class AspectBarSelectorButton implements DComponent {
164 161
 	}
165 162
 	
166 163
 	private void update() {
167
-		if (surface == null)
164
+		if (context == null)
168 165
 			return;
169 166
 		
170 167
 		DShadow newShadow = getShadow();
@@ -174,8 +171,8 @@ public class AspectBarSelectorButton implements DComponent {
174 171
 			if (shape != null)
175 172
 				shape.close();
176 173
 			
177
-			shape = surface.shadowPath(
178
-				z,
174
+			shape = context.shadowPath(
175
+				0,
179 176
 				DPath.roundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, style.roundingRadius),
180 177
 				DTransform2D.IDENTITY,
181 178
 				getColor(),

+ 41
- 45
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarView.java View File

@@ -9,6 +9,7 @@ import java.util.function.Consumer;
9 9
 import java.util.function.Predicate;
10 10
 import org.openzen.drawablegui.BaseComponentGroup;
11 11
 import org.openzen.drawablegui.DComponent;
12
+import org.openzen.drawablegui.DComponentContext;
12 13
 import org.openzen.drawablegui.DSizing;
13 14
 import org.openzen.drawablegui.DFontMetrics;
14 15
 import org.openzen.drawablegui.DPath;
@@ -44,12 +45,9 @@ public class AspectBarView extends BaseComponentGroup {
44 45
 	private final DStyleClass styleClass;
45 46
 	private final IDEAspectBar aspectBar;
46 47
 	
47
-	private DIRectangle bounds;
48
-	private DDrawSurface surface;
49
-	private int z;
50
-	
51
-	private DStylePath path;
48
+	private DComponentContext context;
52 49
 	private AspectBarStyle style;
50
+	private DIRectangle bounds;
53 51
 	private DFontMetrics activeToolbarTitleFontMetrics;
54 52
 	private boolean showWindowControls;
55 53
 	
@@ -83,16 +81,16 @@ public class AspectBarView extends BaseComponentGroup {
83 81
 		aspectBar.active.addListener(this::onActiveChanged);
84 82
 		listener = aspectBar.toolbars.addListener(new ToolbarListListener());
85 83
 		
86
-		minimize = new WindowActionButton(scale -> new ScalableMinimizeIcon(scale), e -> surface.getContext().getWindow().minimize());
84
+		minimize = new WindowActionButton(scale -> new ScalableMinimizeIcon(scale), e -> context.getUIContext().getWindow().minimize());
87 85
 		minimizeRelayout = minimize.getSizing().addListener((a, b) -> layout());
88 86
 		maximizeRestore = new WindowActionButton(ScalableMaximizeIcon::new, e -> {
89
-			if (surface.getContext().getWindow().getWindowState().getValue() == DUIWindow.State.MAXIMIZED)
90
-				surface.getContext().getWindow().restore();
87
+			if (context.getUIContext().getWindow().getWindowState().getValue() == DUIWindow.State.MAXIMIZED)
88
+				context.getUIContext().getWindow().restore();
91 89
 			else
92
-				surface.getContext().getWindow().maximize();
90
+				context.getUIContext().getWindow().maximize();
93 91
 		});
94 92
 		maximizeRestoreRelayout = maximizeRestore.getSizing().addListener((a, b) -> layout());
95
-		close = new WindowActionButton(scale -> new ScalableCloseIcon(scale), e -> surface.getContext().getWindow().close());
93
+		close = new WindowActionButton(scale -> new ScalableCloseIcon(scale), e -> context.getUIContext().getWindow().close());
96 94
 		closeRelayout = close.getSizing().addListener((a, b) -> layout());
97 95
 		
98 96
 		selectorButtons = new LiveMappedList<>(
@@ -100,8 +98,8 @@ public class AspectBarView extends BaseComponentGroup {
100 98
 				bar -> {
101 99
 					LiveBool buttonActive = new LivePredicateBool<>(aspectBar.active, activeBar -> activeBar == bar);
102 100
 					AspectBarSelectorButton button = new AspectBarSelectorButton(DStyleClass.EMPTY, bar.icon, buttonActive, bar.description, e -> aspectBar.active.setValue(bar));
103
-					if (surface != null)
104
-						button.mount(path, z + 1, surface);
101
+					if (context != null)
102
+						button.mount(context);
105 103
 					
106 104
 					return button;
107 105
 				});
@@ -112,35 +110,33 @@ public class AspectBarView extends BaseComponentGroup {
112 110
 	}
113 111
 	
114 112
 	@Override
115
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
116
-		this.surface = surface;
117
-		this.z = z;
118
-		this.path = parent.getChild("aspectbar", styleClass);
119
-		this.style = new AspectBarStyle(surface.getStylesheet(path));
113
+	public void mount(DComponentContext parent) {
114
+		context = parent.getChildContext("aspectbar", styleClass);
115
+		style = context.getStyle(AspectBarStyle::new);
120 116
 		
121
-		activeToolbarTitleFontMetrics = surface.getFontMetrics(style.activeToolbarTitleFont);
122
-		showWindowControls = !surface.getContext().getWindow().hasTitleBar();
117
+		activeToolbarTitleFontMetrics = context.getFontMetrics(style.activeToolbarTitleFont);
118
+		showWindowControls = !context.getUIContext().getWindow().hasTitleBar();
123 119
 		
124 120
 		sizing.setValue(new DSizing(0, style.height));
125 121
 		
126 122
 		for (DComponent selectorButton : selectorButtons)
127
-			selectorButton.mount(path, z + 2, surface);
123
+			selectorButton.mount(context);
128 124
 		
129 125
 		if (activeToolbarComponents != null)
130 126
 			for (DComponent component : activeToolbarComponents)
131
-				component.mount(path, z + 2, surface);
127
+				component.mount(context);
132 128
 		
133
-		minimize.mount(path, z + 2, surface);
134
-		maximizeRestore.mount(path, z + 2, surface);
135
-		close.mount(path, z + 2, surface);
129
+		minimize.mount(context);
130
+		maximizeRestore.mount(context);
131
+		close.mount(context);
136 132
 		
137 133
 		if (topBackground != null)
138 134
 			topBackground.close();
139 135
 		if (bottomBackground != null)
140 136
 			bottomBackground.close();
141 137
 		
142
-		topBackground = surface.fillRect(z, DIRectangle.EMPTY, style.backgroundColor);
143
-		bottomBackground = surface.fillRect(z, DIRectangle.EMPTY, style.backgroundColorBottom);
138
+		topBackground = context.fillRect(0, DIRectangle.EMPTY, style.backgroundColor);
139
+		bottomBackground = context.fillRect(0, DIRectangle.EMPTY, style.backgroundColorBottom);
144 140
 	}
145 141
 	
146 142
 	@Override
@@ -182,7 +178,7 @@ public class AspectBarView extends BaseComponentGroup {
182 178
 	public void setBounds(DIRectangle bounds) {
183 179
 		this.bounds = bounds;
184 180
 		
185
-		if (surface != null) {
181
+		if (context != null) {
186 182
 			layout();
187 183
 			setupActiveBarText();
188 184
 		}
@@ -208,8 +204,8 @@ public class AspectBarView extends BaseComponentGroup {
208 204
 		
209 205
 		activeToolbarComponents = new LiveMappedList<>(aspectBar.controls, control -> {
210 206
 			DComponent result = control.instantiate();
211
-			if (surface != null)
212
-				result.mount(path, z + 2, surface);
207
+			if (context != null)
208
+				result.mount(context);
213 209
 			return result;
214 210
 		});
215 211
 		
@@ -237,9 +233,9 @@ public class AspectBarView extends BaseComponentGroup {
237 233
 				+ (int)(activeToolbarTitleFontMetrics.getAscent() * 0.35f)
238 234
 				+ (bounds.height - style.aspectBarPaddingTop) / 2;
239 235
 		int x = aspectSelectorEndX + style.aspectSelectorToToolbarSpacing;
240
-		activeBarText = surface.drawText(z + 3, style.activeToolbarTitleFont, style.activeToolbarTitleColor, x, y, aspectBar.active.getValue().title);
241
-		activeBarSeparator = surface.fillRect(
242
-				z + 3,
236
+		activeBarText = context.drawText(3, style.activeToolbarTitleFont, style.activeToolbarTitleColor, x, y, aspectBar.active.getValue().title);
237
+		activeBarSeparator = context.fillRect(
238
+				3,
243 239
 				new DIRectangle(
244 240
 					x + activeBarText.getBounds().width + 8,
245 241
 					bounds.y + style.aspectBarPaddingTop + 8,
@@ -282,8 +278,8 @@ public class AspectBarView extends BaseComponentGroup {
282 278
 			activeBarText.setPosition(activeBarX, activeBarY);
283 279
 			
284 280
 			activeBarSeparator.close();
285
-			activeBarSeparator = surface.fillRect(
286
-				z + 3,
281
+			activeBarSeparator = context.fillRect(
282
+				3,
287 283
 				new DIRectangle(
288 284
 					activeBarX + activeBarText.getBounds().width + 8,
289 285
 					bounds.y + style.aspectBarPaddingTop + 8,
@@ -298,8 +294,8 @@ public class AspectBarView extends BaseComponentGroup {
298 294
 			if (windowControlsBackground != null)
299 295
 				windowControlsBackground.close();
300 296
 			
301
-			windowControlsBackground = surface.shadowPath(
302
-					z + 1,
297
+			windowControlsBackground = context.shadowPath(
298
+					1,
303 299
 					windowControlsShape,
304 300
 					DTransform2D.IDENTITY,
305 301
 					style.backgroundColor,
@@ -392,23 +388,23 @@ public class AspectBarView extends BaseComponentGroup {
392 388
 		if (aspectBarShape != null)
393 389
 			aspectBarShape.close();
394 390
 		
395
-		aspectBarShape = surface.shadowPath(z + 1, tracer -> {
391
+		aspectBarShape = context.shadowPath(1, tracer -> {
396 392
 			int height = bounds.height - style.marginBottom;
397 393
 			int baseY = bounds.y + height - style.aspectSelectorBottomSize;
398 394
 			int barBaseX = toX + style.aspectSelectorToToolbarSpacing;
399 395
 			int barBaseY = bounds.y + style.aspectBarPaddingTop;
400 396
 			
401 397
 			tracer.moveTo(bounds.x, baseY);
402
-			tracer.lineTo(toX - 3 * surface.getScale(), baseY);
398
+			tracer.lineTo(toX - 3 * context.getScale(), baseY);
403 399
 			tracer.bezierCubic(
404
-					toX + 0 * surface.getScale(), baseY,
405
-					toX + 2 * surface.getScale(), baseY,
406
-					toX + 3.5f * surface.getScale(), baseY - 4 * surface.getScale());
407
-			tracer.lineTo(barBaseX - 3.5f * surface.getScale(), barBaseY + 4 * surface.getScale());
400
+					toX + 0 * context.getScale(), baseY,
401
+					toX + 2 * context.getScale(), baseY,
402
+					toX + 3.5f * context.getScale(), baseY - 4 * context.getScale());
403
+			tracer.lineTo(barBaseX - 3.5f * context.getScale(), barBaseY + 4 * context.getScale());
408 404
 			tracer.bezierCubic(
409
-					barBaseX - 2 * surface.getScale(), barBaseY,
410
-					barBaseX - 0 * surface.getScale(), barBaseY,
411
-					barBaseX + 3 * surface.getScale(), barBaseY);
405
+					barBaseX - 2 * context.getScale(), barBaseY,
406
+					barBaseX - 0 * context.getScale(), barBaseY,
407
+					barBaseX + 3 * context.getScale(), barBaseY);
412 408
 			
413 409
 			if (showWindowControls) {
414 410
 				int spacingLeft = style.windowControlSpacingLeft;

+ 11
- 15
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/WindowActionButton.java View File

@@ -10,17 +10,17 @@ import java.util.function.Function;
10 10
 import org.openzen.drawablegui.DColorableIcon;
11 11
 import org.openzen.drawablegui.DColorableIconInstance;
12 12
 import org.openzen.drawablegui.DComponent;
13
+import org.openzen.drawablegui.DComponentContext;
13 14
 import org.openzen.drawablegui.DSizing;
14 15
 import org.openzen.drawablegui.DMouseEvent;
15 16
 import org.openzen.drawablegui.DTransform2D;
16 17
 import org.openzen.drawablegui.DIRectangle;
17
-import org.openzen.drawablegui.draw.DDrawSurface;
18 18
 import org.openzen.drawablegui.draw.DDrawnRectangle;
19 19
 import org.openzen.drawablegui.listeners.ListenerHandle;
20 20
 import org.openzen.drawablegui.live.LiveBool;
21 21
 import org.openzen.drawablegui.live.LiveObject;
22 22
 import org.openzen.drawablegui.live.MutableLiveObject;
23
-import org.openzen.drawablegui.style.DStylePath;
23
+import org.openzen.drawablegui.style.DStyleClass;
24 24
 import org.openzen.zenscript.ide.ui.icons.ScalableCloseIcon;
25 25
 
26 26
 /**
@@ -36,12 +36,11 @@ public class WindowActionButton implements DComponent {
36 36
 	private LiveBool windowFocused;
37 37
 	private ListenerHandle<LiveBool.Listener> windowFocusedListener;
38 38
 	
39
+	private DComponentContext context;
39 40
 	private DColorableIcon icon;
40 41
 	private DIRectangle bounds;
41 42
 	private boolean hover;
42 43
 	private boolean press;
43
-	private DDrawSurface surface;
44
-	private int z;
45 44
 	
46 45
 	private DDrawnRectangle background;
47 46
 	private DColorableIconInstance drawnIcon;
@@ -52,19 +51,18 @@ public class WindowActionButton implements DComponent {
52 51
 	}
53 52
 
54 53
 	@Override
55
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
56
-		this.surface = surface;
57
-		this.z = z;
54
+	public void mount(DComponentContext parent) {
55
+		context = parent.getChildContext("windowactionbutton", DStyleClass.EMPTY);
58 56
 		
59
-		windowFocused = surface.getContext().getWindow().getActive();
57
+		windowFocused = context.getUIContext().getWindow().getActive();
60 58
 		windowFocusedListener = windowFocused.addListener((a, b) -> update());
61 59
 		
62
-		icon = scalableIcon == null ? null : scalableIcon.apply(surface.getScale());
60
+		icon = scalableIcon == null ? null : scalableIcon.apply(context.getScale());
63 61
 		sizing.setValue(new DSizing(
64
-				(int)(48 * surface.getScale()),
65
-				(int)(24 * surface.getScale())));
62
+				(int)(48 * context.getScale()),
63
+				(int)(24 * context.getScale())));
66 64
 		
67
-		background = surface.fillRect(z, DIRectangle.EMPTY, getBackgroundColor());
65
+		background = context.fillRect(0, DIRectangle.EMPTY, getBackgroundColor());
68 66
 	}
69 67
 	
70 68
 	@Override
@@ -105,7 +103,7 @@ public class WindowActionButton implements DComponent {
105 103
 			
106 104
 			int iconX = bounds.x + (int)(bounds.width - icon.getNominalWidth()) / 2;
107 105
 			int iconY = bounds.y + (int)(bounds.height - icon.getNominalHeight()) / 2;
108
-			drawnIcon = new DColorableIconInstance(surface, z + 1, icon, DTransform2D.translate(iconX, iconY), getIconColor());
106
+			drawnIcon = new DColorableIconInstance(context.surface, context.z + 1, icon, DTransform2D.translate(iconX, iconY), getIconColor());
109 107
 		}
110 108
 	}
111 109
 
@@ -151,12 +149,10 @@ public class WindowActionButton implements DComponent {
151 149
 	
152 150
 	private int getBackgroundColor() {
153 151
 		int color = 0xFFFFFFFF;
154
-		int iconColor = windowFocused.getValue() ? 0xFF000000 : 0xFF999999;
155 152
 		
156 153
 		if (hover) {
157 154
 			if (icon instanceof ScalableCloseIcon) {
158 155
 				color = 0xFFE81123;
159
-				iconColor = 0xFFFFFFFF;
160 156
 			} else {
161 157
 				color = 0xFFE0E0E0;
162 158
 			}

+ 64
- 55
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java View File

@@ -10,6 +10,7 @@ import java.io.Reader;
10 10
 import java.util.ArrayList;
11 11
 import java.util.List;
12 12
 import org.openzen.drawablegui.DComponent;
13
+import org.openzen.drawablegui.DComponentContext;
13 14
 import org.openzen.drawablegui.DSizing;
14 15
 import org.openzen.drawablegui.DFont;
15 16
 import org.openzen.drawablegui.DFontFamily;
@@ -31,7 +32,6 @@ import org.openzen.zenscript.lexer.ZSTokenParser;
31 32
 import org.openzen.zenscript.lexer.ZSTokenType;
32 33
 import org.openzen.drawablegui.DUIContext;
33 34
 import org.openzen.drawablegui.Destructible;
34
-import org.openzen.drawablegui.draw.DDrawSurface;
35 35
 import org.openzen.drawablegui.draw.DDrawnRectangle;
36 36
 import org.openzen.drawablegui.draw.DDrawnShape;
37 37
 import org.openzen.drawablegui.draw.DDrawnText;
@@ -41,7 +41,6 @@ import org.openzen.drawablegui.live.LiveBool;
41 41
 import org.openzen.drawablegui.live.MutableLiveObject;
42 42
 import org.openzen.drawablegui.live.SimpleLiveBool;
43 43
 import org.openzen.drawablegui.style.DStyleClass;
44
-import org.openzen.drawablegui.style.DStylePath;
45 44
 import org.openzen.zenscript.ide.ui.icons.SaveIcon;
46 45
 import org.openzen.zenscript.ide.ui.icons.ShadedCodeIcon;
47 46
 import org.openzen.zenscript.ide.ui.icons.ShadedSaveIcon;
@@ -61,9 +60,8 @@ public class SourceEditor implements DComponent {
61 60
 	private final ListenerHandle<TokenModel.Listener> tokenListener;
62 61
 	private final SimpleLiveBool unchanged = new SimpleLiveBool(true);
63 62
 	
63
+	private DComponentContext context;
64 64
 	private DIRectangle bounds;
65
-	private int z;
66
-	private DDrawSurface surface;
67 65
 	private SourceEditorStyle style;
68 66
 	private DTimerHandle blinkTimer;
69 67
 	
@@ -136,29 +134,28 @@ public class SourceEditor implements DComponent {
136 134
 	}
137 135
 
138 136
 	@Override
139
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
140
-		if (surface != null)
137
+	public void mount(DComponentContext parent) {
138
+		if (context != null)
141 139
 			unmount();
142 140
 		
143
-		this.surface = surface;
144
-		this.z = z;
145
-		this.style = new SourceEditorStyle(surface.getStylesheet(parent.getChild("sourceeditor", styleClass)));
141
+		context = parent.getChildContext("sourceeditor", styleClass);
142
+		style = context.getStyle(SourceEditorStyle::new);
146 143
 		
147
-		fontMetrics = surface.getFontMetrics(font);
144
+		fontMetrics = context.getFontMetrics(font);
148 145
 		textLineHeight = fontMetrics.getAscent() + fontMetrics.getDescent();
149 146
 		fullLineHeight = textLineHeight + fontMetrics.getLeading() + style.extraLineSpacing;
150 147
 		selectionLineHeight = textLineHeight + style.selectionPaddingTop + style.selectionPaddingBottom;
151 148
 		
152 149
 		sizing.setValue(new DSizing(0, fullLineHeight * tokens.getLineCount()));
153 150
 		
154
-		blinkTimer = surface.getContext().setTimer(300, this::blink);
151
+		blinkTimer = context.getUIContext().setTimer(300, this::blink);
155 152
 		
156
-		selection = surface.fillRect(z + 2, DIRectangle.EMPTY, style.selectionColor);
157
-		cursor = surface.fillRect(z + 4, DIRectangle.EMPTY, style.cursorColor);
158
-		currentLineHighlight = surface.fillRect(z + 1, DIRectangle.EMPTY, style.currentLineHighlight);
153
+		selection = context.fillRect(2, DIRectangle.EMPTY, style.selectionColor);
154
+		cursor = context.fillRect(4, DIRectangle.EMPTY, style.cursorColor);
155
+		currentLineHighlight = context.fillRect(1, DIRectangle.EMPTY, style.currentLineHighlight);
159 156
 		
160 157
 		for (int i = 0; i < tokens.getLineCount(); i++)
161
-			lineNumbers.add(surface.drawText(z + 3, font, style.lineBarTextColor, 0, 0, Integer.toString(i + 1)));
158
+			lineNumbers.add(context.drawText(3, font, style.lineBarTextColor, 0, 0, Integer.toString(i + 1)));
162 159
 		
163 160
 		for (TokenLine line : tokens.getLines())
164 161
 			drawnTokens.add(lineToTokens(line));
@@ -171,7 +168,7 @@ public class SourceEditor implements DComponent {
171 168
 	public void unmount() {
172 169
 		window.aspectBar.toolbars.remove(editToolbar);
173 170
 		
174
-		surface = null;
171
+		context = null;
175 172
 		
176 173
 		if (background != null) {
177 174
 			background.close();
@@ -249,9 +246,9 @@ public class SourceEditor implements DComponent {
249 246
 			lineBarBackground.close();
250 247
 		if (lineBarLine != null)
251 248
 			lineBarLine.close();
252
-		background = surface.fillRect(z, new DIRectangle(bounds.x + lineBarWidth, bounds.y, bounds.width - lineBarWidth, bounds.height), style.backgroundColor);
253
-		lineBarBackground = surface.fillRect(z, new DIRectangle(bounds.x, bounds.y, lineBarWidth, bounds.height), style.lineBarBackgroundColor);
254
-		lineBarLine = surface.strokePath(z + 1, tracer -> {
249
+		background = context.fillRect(0, new DIRectangle(bounds.x + lineBarWidth, bounds.y, bounds.width - lineBarWidth, bounds.height), style.backgroundColor);
250
+		lineBarBackground = context.fillRect(0, new DIRectangle(bounds.x, bounds.y, lineBarWidth, bounds.height), style.lineBarBackgroundColor);
251
+		lineBarLine = context.strokePath(1, tracer -> {
255 252
 				tracer.moveTo(bounds.x + lineBarWidth, bounds.y);
256 253
 				tracer.lineTo(bounds.x + lineBarWidth, bounds.y + bounds.height);
257 254
 			}, DTransform2D.IDENTITY, style.lineBarStrokeColor, style.lineBarStrokeWidth);
@@ -269,17 +266,17 @@ public class SourceEditor implements DComponent {
269 266
 	
270 267
 	@Override
271 268
 	public void onMouseEnter(DMouseEvent e) {
272
-		surface.getContext().setCursor(DUIContext.Cursor.TEXT);
269
+		context.getUIContext().setCursor(DUIContext.Cursor.TEXT);
273 270
 	}
274 271
 	
275 272
 	@Override
276 273
 	public void onMouseExit(DMouseEvent e) {
277
-		surface.getContext().setCursor(DUIContext.Cursor.NORMAL);
274
+		context.getUIContext().setCursor(DUIContext.Cursor.NORMAL);
278 275
 	}
279 276
 	
280 277
 	@Override
281 278
 	public void onMouseClick(DMouseEvent e) {
282
-		surface.getContext().getWindow().focus(this);
279
+		context.getUIContext().getWindow().focus(this);
283 280
 		
284 281
 		SourcePosition position = getPositionAt(e.x, e.y);
285 282
 		if (e.isDoubleClick()) {
@@ -329,17 +326,17 @@ public class SourceEditor implements DComponent {
329 326
 				SourcePosition to = SourcePosition.max(cursorStart, cursorEnd);
330 327
 				
331 328
 				int fromX = getX(from);
332
-				multiLineSelection.add(surface.fillRect(
333
-						z + 2,
329
+				multiLineSelection.add(context.fillRect(
330
+						2,
334 331
 						new DIRectangle(fromX, getY(from), bounds.width - fromX, selectionLineHeight),
335 332
 						style.selectionColor));
336 333
 				
337 334
 				for (int i = from.line + 1; i < to.line; i++) {
338
-					multiLineSelection.add(surface.fillRect(z + 2, new DIRectangle(x, lineToY(i), bounds.width - x, selectionLineHeight), style.selectionColor));
335
+					multiLineSelection.add(context.fillRect(2, new DIRectangle(x, lineToY(i), bounds.width - x, selectionLineHeight), style.selectionColor));
339 336
 				}
340 337
 				
341 338
 				int toX = getX(to);
342
-				multiLineSelection.add(surface.fillRect(z + 2, new DIRectangle(x, getY(to), Math.max(0, toX - x), selectionLineHeight), style.selectionColor));
339
+				multiLineSelection.add(context.fillRect(2, new DIRectangle(x, getY(to), Math.max(0, toX - x), selectionLineHeight), style.selectionColor));
343 340
 				selection.setRectangle(DIRectangle.EMPTY);
344 341
 			}
345 342
 		} else {
@@ -364,35 +361,38 @@ public class SourceEditor implements DComponent {
364 361
 		setCursor(start, getPositionAt(e.x, e.y));
365 362
 	}
366 363
 	
364
+	private void moveLines(boolean shift, int lines) {
365
+		if (cursorEnd == null)
366
+			return;
367
+		
368
+		int line = cursorEnd.line + lines;
369
+		if (line < 0)
370
+			line = 0;
371
+		if (line >= tokens.getLineCount())
372
+			line = tokens.getLineCount() - 1;
373
+		
374
+		SourcePosition position = new SourcePosition(
375
+				tokens,
376
+				line,
377
+				Math.min(tokens.getLineLength(line), cursorEnd.offset));
378
+		setCursor(shift ? cursorStart : position, position);
379
+	}
380
+	
367 381
 	@Override
368 382
 	public void onKeyPressed(DKeyEvent e) {
369 383
 		boolean shift = e.has(DKeyEvent.SHIFT);
370 384
 		switch (e.keyCode) {
385
+			case PAGE_UP:
386
+				moveLines(shift, -getWindowLines());
387
+				break;
388
+			case PAGE_DOWN:
389
+				moveLines(shift, getWindowLines());
390
+				break;
371 391
 			case UP:
372
-				if (cursorEnd == null || cursorEnd.line == 0)
373
-					return;
374
-				
375
-				{
376
-					int line = cursorEnd.line - 1;
377
-					SourcePosition position = new SourcePosition(
378
-							tokens,
379
-							line,
380
-							Math.min(tokens.getLineLength(line), cursorEnd.offset));
381
-					setCursor(shift ? cursorStart : position, position);
382
-				}
392
+				moveLines(shift, -1);
383 393
 				break;
384 394
 			case DOWN:
385
-				if (cursorEnd == null || cursorEnd.line >= tokens.getLineCount() - 1)
386
-					return;
387
-				
388
-				{
389
-					int line = cursorEnd.line + 1;
390
-					SourcePosition position = new SourcePosition(
391
-							tokens,
392
-							line,
393
-							Math.min(tokens.getLineLength(line), cursorEnd.offset));
394
-					setCursor(shift ? cursorStart : position, position);
395
-				}
395
+				moveLines(shift, 1);
396 396
 				break;
397 397
 			case LEFT:
398 398
 				if (cursorEnd == null || (cursorEnd.line == 0 && cursorEnd.offset == 0))
@@ -470,7 +470,7 @@ public class SourceEditor implements DComponent {
470 470
 		String extract = tokens.extract(
471 471
 				SourcePosition.min(cursorStart, cursorEnd),
472 472
 				SourcePosition.max(cursorStart, cursorEnd));
473
-		surface.getContext().getClipboard().copyAsString(extract);
473
+		context.getUIContext().getClipboard().copyAsString(extract);
474 474
 	}
475 475
 	
476 476
 	private void cut() {
@@ -483,7 +483,7 @@ public class SourceEditor implements DComponent {
483 483
 	}
484 484
 	
485 485
 	private void paste() {
486
-		String text = surface.getContext().getClipboard().getAsString();
486
+		String text = context.getUIContext().getClipboard().getAsString();
487 487
 		if (text == null)
488 488
 			return;
489 489
 		
@@ -540,7 +540,7 @@ public class SourceEditor implements DComponent {
540 540
 		if (deleteSelection())
541 541
 			return;
542 542
 		
543
-		if (cursorEnd.line > 0) {
543
+		/*if (cursorEnd.line > 0) {
544 544
 			String indent = tokens.getLine(cursorEnd.line - 1).getIndent(); // TODO: get nominal indent for current scope
545 545
 			if (cursorEnd.offset == indent.length()) {
546 546
 				// remove entire indent
@@ -550,7 +550,7 @@ public class SourceEditor implements DComponent {
550 550
 				setCursor(deleteFrom, deleteFrom);
551 551
 				return;
552 552
 			}
553
-		}
553
+		}*/
554 554
 		
555 555
 		if (cursorEnd.offset == 0) {
556 556
 			if (cursorEnd.line == 0)
@@ -614,7 +614,8 @@ public class SourceEditor implements DComponent {
614 614
 	}
615 615
 	
616 616
 	public void scrollTo(SourcePosition position) {
617
-		surface.getContext().scrollInView(getX(position), getY(position), 2, selectionLineHeight);
617
+		if (context.scrollContext != null)
618
+			context.scrollContext.scrollInView(getX(position), getY(position), 2, selectionLineHeight);
618 619
 	}
619 620
 	
620 621
 	private void blink() {
@@ -624,6 +625,14 @@ public class SourceEditor implements DComponent {
624 625
 		}
625 626
 	}
626 627
 	
628
+	private int getWindowLines() {
629
+		if (context.scrollContext == null) {
630
+			return 20;
631
+		} else {
632
+			return context.scrollContext.getViewportHeight() / fullLineHeight;
633
+		}
634
+	}
635
+	
627 636
 	public SourcePosition getPositionAt(int x, int y) {
628 637
 		int line = yToLine(y);
629 638
 		int offset = xToOffset(line, x);
@@ -730,7 +739,7 @@ public class SourceEditor implements DComponent {
730 739
 		List<DDrawnText> tokenLine = new ArrayList<>();
731 740
 		for (ZSToken token : line.getTokens()) {
732 741
 			String content = getDisplayContent(token);
733
-			tokenLine.add(surface.drawText(z + 3, font, TokenClass.get(token.type).color, 0, 0, content));
742
+			tokenLine.add(context.drawText(3, font, TokenClass.get(token.type).color, 0, 0, content));
734 743
 		}
735 744
 		return tokenLine;
736 745
 	}
@@ -745,7 +754,7 @@ public class SourceEditor implements DComponent {
745 754
 				String str = Integer.toString(lineNumbers.size() + 1);
746 755
 				int x = bounds.x + lineBarWidth - style.lineBarSpacingRight - style.lineBarMargin - fontMetrics.getWidth(str);
747 756
 				int y = bounds.y + style.selectionPaddingTop + lineNumbers.size() * fullLineHeight + fontMetrics.getAscent();
748
-				lineNumbers.add(surface.drawText(z + 3, font, style.lineBarTextColor, x, y, str));
757
+				lineNumbers.add(context.drawText(3, font, style.lineBarTextColor, x, y, str));
749 758
 				
750 759
 				drawnTokens.add(index, lineToTokens(tokens.getLine(index)));
751 760
 				layoutLines(index);

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

@@ -8,12 +8,12 @@ package org.openzen.zenscript.ide.ui.view.output;
8 8
 import java.util.ArrayList;
9 9
 import java.util.List;
10 10
 import org.openzen.drawablegui.DComponent;
11
+import org.openzen.drawablegui.DComponentContext;
11 12
 import org.openzen.drawablegui.DFontMetrics;
12 13
 import org.openzen.drawablegui.DIRectangle;
13 14
 import org.openzen.drawablegui.DSizing;
14 15
 import org.openzen.drawablegui.DTransform2D;
15 16
 import org.openzen.drawablegui.Destructible;
16
-import org.openzen.drawablegui.draw.DDrawSurface;
17 17
 import org.openzen.drawablegui.draw.DDrawnShape;
18 18
 import org.openzen.drawablegui.draw.DDrawnText;
19 19
 import org.openzen.drawablegui.listeners.ListenerHandle;
@@ -21,7 +21,6 @@ import org.openzen.drawablegui.live.LiveList;
21 21
 import org.openzen.drawablegui.live.LiveObject;
22 22
 import org.openzen.drawablegui.live.MutableLiveObject;
23 23
 import org.openzen.drawablegui.style.DStyleClass;
24
-import org.openzen.drawablegui.style.DStylePath;
25 24
 
26 25
 /**
27 26
  *
@@ -32,8 +31,7 @@ public class OutputView implements DComponent {
32 31
 	private final DStyleClass styleClass;
33 32
 	private final LiveList<OutputLine> lines;
34 33
 	
35
-	private DDrawSurface surface;
36
-	private int z;
34
+	private DComponentContext context;
37 35
 	private DIRectangle bounds;
38 36
 	private OutputViewStyle style;
39 37
 	private DFontMetrics fontMetrics;
@@ -48,16 +46,13 @@ public class OutputView implements DComponent {
48 46
 	}
49 47
 
50 48
 	@Override
51
-	public void mount(DStylePath parent, int z, DDrawSurface surface) {
52
-		if (this.surface != null)
49
+	public void mount(DComponentContext parent) {
50
+		if (context != null)
53 51
 			unmount();
54 52
 		
55
-		this.surface = surface;
56
-		this.z = z;
57
-		
58
-		DStylePath path = parent.getChild("outputview", styleClass);
59
-		style = new OutputViewStyle(surface.getStylesheet(path));
60
-		fontMetrics = surface.getFontMetrics(style.font);
53
+		context = parent.getChildContext("outputview", styleClass);
54
+		style = context.getStyle(OutputViewStyle::new);
55
+		fontMetrics = context.getFontMetrics(style.font);
61 56
 		
62 57
 		for (OutputLine line : lines)
63 58
 			outputText.add(draw(line));
@@ -68,7 +63,7 @@ public class OutputView implements DComponent {
68 63
 	
69 64
 	@Override
70 65
 	public void unmount() {
71
-		surface = null;
66
+		context = null;
72 67
 		
73 68
 		if (shape != null) {
74 69
 			shape.close();
@@ -102,7 +97,7 @@ public class OutputView implements DComponent {
102 97
 		this.bounds = bounds;
103 98
 		
104 99
 		DIRectangle available = style.margin.apply(bounds);
105
-		shape = surface.shadowPath(z, style.shape.instance(available), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
100
+		shape = context.shadowPath(0, style.shape.instance(available), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
106 101
 		
107 102
 		layout(0);
108 103
 	}
@@ -119,7 +114,7 @@ public class OutputView implements DComponent {
119 114
 	private List<DDrawnText> draw(OutputLine line) {
120 115
 		List<DDrawnText> lineText = new ArrayList<>();
121 116
 		for (OutputSpan span : line.spans)
122
-			lineText.add(surface.drawText(z + 1, style.font, span.getColor(), 0, 0, span.getText()));
117
+			lineText.add(context.drawText(1, style.font, span.getColor(), 0, 0, span.getText()));
123 118
 		return lineText;
124 119
 	}
125 120
 	

+ 8
- 4
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenParser.java View File

@@ -6,9 +6,9 @@
6 6
 package org.openzen.zenscript.lexer;
7 7
 
8 8
 import java.io.IOException;
9
-import java.io.Reader;
10 9
 import org.openzen.zencode.shared.SourceFile;
11 10
 import org.openzen.zenscript.codemodel.WhitespaceInfo;
11
+import org.openzen.zenscript.parser.BracketExpressionParser;
12 12
 
13 13
 /**
14 14
  *
@@ -27,12 +27,16 @@ public class ZSTokenParser extends LLParserTokenStream<ZSTokenType, ZSToken> {
27 27
 				new ZSTokenFactory(spacesPerTab));
28 28
 	}
29 29
 	
30
-	public static ZSTokenParser create(SourceFile file, int spacesPerTab) throws IOException {
31
-		return new ZSTokenParser(createRaw(file, new ReaderCharReader(file.open()), spacesPerTab));
30
+	public static ZSTokenParser create(SourceFile file, BracketExpressionParser bracketParser, int spacesPerTab) throws IOException {
31
+		return new ZSTokenParser(createRaw(file, new ReaderCharReader(file.open()), spacesPerTab), bracketParser);
32 32
 	}
33 33
 	
34
-	public ZSTokenParser(TokenStream<ZSTokenType, ZSToken> parser) {
34
+	public final BracketExpressionParser bracketParser;
35
+	
36
+	public ZSTokenParser(TokenStream<ZSTokenType, ZSToken> parser, BracketExpressionParser bracketParser) {
35 37
 		super(parser);
38
+		
39
+		this.bracketParser = bracketParser;
36 40
 	}
37 41
 	
38 42
 	public SourceFile getFile() {

+ 27
- 0
Parser/src/main/java/org/openzen/zenscript/parser/BracketExpressionParser.java View File

@@ -0,0 +1,27 @@
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.parser;
7
+
8
+import org.openzen.zencode.shared.CodePosition;
9
+import org.openzen.zencode.shared.CompileException;
10
+import org.openzen.zenscript.lexer.ZSTokenParser;
11
+import org.openzen.zenscript.parser.expression.ParsedExpression;
12
+
13
+/**
14
+ *
15
+ * @author Hoofdgebruiker
16
+ */
17
+public interface BracketExpressionParser {
18
+	/**
19
+	 * Parses the given bracket expression. Note that the "&lt;" token is already
20
+	 * processed.
21
+	 * 
22
+	 * @param position start of the expression (which is the location of the &gt; token)
23
+	 * @param tokens tokens to be parsed
24
+	 * @return parsed expression
25
+	 */
26
+	ParsedExpression parse(CodePosition position, ZSTokenParser tokens) throws CompileException;
27
+}

+ 2
- 0
Parser/src/main/java/org/openzen/zenscript/parser/ParsedDefinition.java View File

@@ -78,5 +78,7 @@ public abstract class ParsedDefinition {
78 78
 	
79 79
 	public abstract void listMembers(BaseScope scope, PrecompilationState state);
80 80
 	
81
+	public abstract void precompile(BaseScope scope, PrecompilationState state);
82
+	
81 83
 	public abstract void compileCode(BaseScope scope, PrecompilationState state);
82 84
 }

+ 9
- 7
Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java View File

@@ -40,20 +40,20 @@ import org.openzen.zenscript.parser.statements.ParsedStatement;
40 40
  * @author Hoofdgebruiker
41 41
  */
42 42
 public class ParsedFile {
43
-	public static ParsedFile parse(ZSPackage pkg, File file) throws IOException {
44
-		return parse(pkg, new FileSourceFile(file.getName(), file));
43
+	public static ParsedFile parse(ZSPackage pkg, BracketExpressionParser bracketParser, File file) throws IOException {
44
+		return parse(pkg, bracketParser, new FileSourceFile(file.getName(), file));
45 45
 	}
46 46
 	
47
-	public static ParsedFile parse(ZSPackage pkg, String filename, String content) {
47
+	public static ParsedFile parse(ZSPackage pkg, BracketExpressionParser bracketParser, String filename, String content) {
48 48
 		try {
49
-			return parse(pkg, new LiteralSourceFile(filename, content));
49
+			return parse(pkg, bracketParser, new LiteralSourceFile(filename, content));
50 50
 		} catch (IOException ex) {
51 51
 			throw new AssertionError(); // shouldn't happen
52 52
 		}
53 53
 	}
54 54
 	
55
-	public static ParsedFile parse(ZSPackage pkg, SourceFile file) throws IOException {
56
-		ZSTokenParser tokens = ZSTokenParser.create(file, 4);
55
+	public static ParsedFile parse(ZSPackage pkg, BracketExpressionParser bracketParser, SourceFile file) throws IOException {
56
+		ZSTokenParser tokens = ZSTokenParser.create(file, bracketParser, 4);
57 57
 		return parse(pkg, tokens);
58 58
 	}
59 59
 	
@@ -193,7 +193,9 @@ public class ParsedFile {
193 193
 		for (ParsedDefinition definition : this.definitions) {
194 194
 			definition.listMembers(scope, state);
195 195
 		}
196
-		
196
+		for (ParsedDefinition definition : this.definitions) {
197
+			definition.precompile(scope, state);
198
+		}
197 199
 		for (ParsedDefinition definition : this.definitions) {
198 200
 			definition.compileCode(scope, state);
199 201
 		}

+ 57
- 0
Parser/src/main/java/org/openzen/zenscript/parser/PrefixedBracketParser.java View File

@@ -0,0 +1,57 @@
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.parser;
7
+
8
+import java.util.HashMap;
9
+import java.util.Map;
10
+import org.openzen.zencode.shared.CodePosition;
11
+import org.openzen.zencode.shared.CompileException;
12
+import org.openzen.zencode.shared.CompileExceptionCode;
13
+import org.openzen.zenscript.lexer.ZSToken;
14
+import org.openzen.zenscript.lexer.ZSTokenParser;
15
+import org.openzen.zenscript.lexer.ZSTokenType;
16
+import org.openzen.zenscript.parser.expression.ParsedExpression;
17
+
18
+/**
19
+ *
20
+ * @author Hoofdgebruiker
21
+ */
22
+public class PrefixedBracketParser implements BracketExpressionParser {
23
+	private final Map<String, BracketExpressionParser> subParsers = new HashMap<>();
24
+	private final BracketExpressionParser defaultParser;
25
+	
26
+	public PrefixedBracketParser(BracketExpressionParser defaultParser) {
27
+		this.defaultParser = defaultParser;
28
+	}
29
+	
30
+	public void register(String name, BracketExpressionParser parser) {
31
+		subParsers.put(name, parser);
32
+	}
33
+
34
+	@Override
35
+	public ParsedExpression parse(CodePosition position, ZSTokenParser tokens) {
36
+		if (defaultParser == null) {
37
+			ZSToken start = tokens.required(ZSTokenType.T_IDENTIFIER, "identifier expected");
38
+			tokens.required(ZSTokenType.T_COLON, ": expected");
39
+			BracketExpressionParser subParser = subParsers.get(start.content);
40
+			if (subParser == null)
41
+				throw new CompileException(position, CompileExceptionCode.INVALID_BRACKET_EXPRESSION, "Invalid bracket expression");
42
+			
43
+			return subParser.parse(position, tokens);
44
+		} else {
45
+			tokens.pushMark();
46
+			ZSToken start = tokens.next();
47
+			if (start.type == ZSTokenType.T_IDENTIFIER && subParsers.containsKey(start.content)) {
48
+				tokens.popMark();
49
+				tokens.required(ZSTokenType.T_COLON, ": expected");
50
+				return subParsers.get(start.content).parse(position, tokens);
51
+			} else {
52
+				tokens.reset();
53
+				return defaultParser.parse(position, tokens);
54
+			}
55
+		}
56
+	}
57
+}

+ 73
- 0
Parser/src/main/java/org/openzen/zenscript/parser/SimpleBracketSubParser.java View File

@@ -0,0 +1,73 @@
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.parser;
7
+
8
+import org.openzen.zencode.shared.CodePosition;
9
+import org.openzen.zenscript.codemodel.expression.CallArguments;
10
+import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
11
+import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
12
+import org.openzen.zenscript.codemodel.member.ref.FunctionalMemberRef;
13
+import org.openzen.zenscript.codemodel.partial.IPartialExpression;
14
+import org.openzen.zenscript.codemodel.scope.ExpressionScope;
15
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
16
+import org.openzen.zenscript.codemodel.type.ITypeID;
17
+import org.openzen.zenscript.lexer.ZSTokenParser;
18
+import org.openzen.zenscript.lexer.ZSTokenType;
19
+import org.openzen.zenscript.parser.expression.ParsedExpression;
20
+
21
+/**
22
+ *
23
+ * @author Hoofdgebruiker
24
+ */
25
+public class SimpleBracketSubParser implements BracketExpressionParser {
26
+	private final FunctionalMemberRef method;
27
+	private final ITypeID targetType;
28
+	
29
+	public SimpleBracketSubParser(GlobalTypeRegistry registry, FunctionalMemberRef method) {
30
+		if (!method.isStatic())
31
+			throw new IllegalArgumentException("Method must be static");
32
+		if (method.header.getNumberOfTypeParameters() > 0)
33
+			throw new IllegalArgumentException("Method cannot have type parameters");
34
+		
35
+		this.method = method;
36
+		this.targetType = registry.getForDefinition(method.getTarget().definition);
37
+	}
38
+
39
+	@Override
40
+	public ParsedExpression parse(CodePosition position, ZSTokenParser tokens) {
41
+		StringBuilder string = new StringBuilder();
42
+		while (tokens.optional(ZSTokenType.T_GREATER) == null) {
43
+			string.append(tokens.next().content);
44
+			string.append(tokens.getLastWhitespace());
45
+		}
46
+		return new StaticMethodCallExpression(position, string.toString());
47
+	}
48
+	
49
+	private class StaticMethodCallExpression extends ParsedExpression {
50
+		private final String value;
51
+		
52
+		public StaticMethodCallExpression(CodePosition position, String value) {
53
+			super(position);
54
+			
55
+			this.value = value;
56
+		}
57
+
58
+		@Override
59
+		public IPartialExpression compile(ExpressionScope scope) {
60
+			return new CallStaticExpression(position, targetType, method, method.header, new CallArguments(new ConstantStringExpression(position, value)), scope);
61
+		}
62
+
63
+		@Override
64
+		public boolean hasStrongType() {
65
+			return true;
66
+		}
67
+
68
+		@Override
69
+		public ITypeID precompileForType(ExpressionScope scope, PrecompilationState state) {
70
+			return method.header.returnType;
71
+		}
72
+	}
73
+}

+ 7
- 0
Parser/src/main/java/org/openzen/zenscript/parser/definitions/BaseParsedDefinition.java View File

@@ -53,6 +53,13 @@ public abstract class BaseParsedDefinition extends ParsedDefinition {
53 53
 		for (ParsedDefinitionMember member : members)
54 54
 			state.register(innerScope, member);
55 55
 	}
56
+	
57
+	@Override
58
+	public void precompile(BaseScope scope, PrecompilationState state) {
59
+		DefinitionScope innerScope = new DefinitionScope(scope, getCompiled());
60
+		for (ParsedDefinitionMember member : members)
61
+			state.precompile(member.getCompiled());
62
+	}
56 63
 
57 64
 	@Override
58 65
 	public void compileCode(BaseScope scope, PrecompilationState state) {

+ 5
- 0
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedAlias.java View File

@@ -79,6 +79,11 @@ public class ParsedAlias extends ParsedDefinition {
79 79
 	public void listMembers(BaseScope scope, PrecompilationState state) {
80 80
 		// nothing to do
81 81
 	}
82
+	
83
+	@Override
84
+	public void precompile(BaseScope scope, PrecompilationState state) {
85
+		// nothing to do
86
+	}
82 87
 
83 88
 	@Override
84 89
 	public void compileCode(BaseScope scope, PrecompilationState state) {

+ 8
- 5
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedFunction.java View File

@@ -69,12 +69,9 @@ public class ParsedFunction extends ParsedDefinition {
69 69
 	public void listMembers(BaseScope scope, PrecompilationState state) {
70 70
 		
71 71
 	}
72
-
72
+	
73 73
 	@Override
74
-	public void compileCode(BaseScope scope, PrecompilationState state) {
75
-		FunctionScope innerScope = new FunctionScope(scope, compiled.header);
76
-		compiled.setCode(body.compile(innerScope, compiled.header));
77
-		
74
+	public void precompile(BaseScope scope, PrecompilationState state) {
78 75
 		if (compiled.header.returnType == BasicTypeID.UNDETERMINED) {
79 76
 			ITypeID result = body.precompileForResultType(new FunctionScope(scope, compiled.header), state);
80 77
 			if (result == null)
@@ -82,4 +79,10 @@ public class ParsedFunction extends ParsedDefinition {
82 79
 			compiled.header = compiled.header.withReturnType(result);
83 80
 		}
84 81
 	}
82
+
83
+	@Override
84
+	public void compileCode(BaseScope scope, PrecompilationState state) {
85
+		FunctionScope innerScope = new FunctionScope(scope, compiled.header);
86
+		compiled.setCode(body.compile(innerScope, compiled.header));
87
+	}
85 88
 }

+ 6
- 0
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java View File

@@ -358,6 +358,12 @@ public abstract class ParsedExpression {
358 358
 					// try! can thus be used to convert from exception-based to result-based and vice versa
359 359
 					return new ParsedTryRethrowExpression(position, readUnaryExpression(position, parser, options));
360 360
 				}
361
+			case T_LESS:// bracket expression
362
+				parser.next();
363
+				if (parser.bracketParser == null)
364
+					throw new CompileException(position, CompileExceptionCode.NO_BRACKET_PARSER, "Bracket expression detected but no bracket parser present");
365
+				
366
+				return parser.bracketParser.parse(position, parser);
361 367
 			default:
362 368
 				return readPostfixExpression(position, parser, options);
363 369
 		}

+ 2
- 2
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java View File

@@ -50,7 +50,7 @@ public class ParsedExpressionFunction extends ParsedExpression {
50 50
 		for (ITypeID hint : scope.hints) {
51 51
 			if (hint instanceof FunctionTypeID) {
52 52
 				FunctionTypeID functionHint = (FunctionTypeID) hint;
53
-				if (header.canCastTo(scope, functionHint.header)) {
53
+				if (header.canOverride(scope, functionHint.header)) {
54 54
 					if (header != definedHeader)
55 55
 						throw new CompileException(position, CompileExceptionCode.MULTIPLE_MATCHING_HINTS, "Ambiguity trying to resolve function types, can't decide for the type");
56 56
 					
@@ -87,7 +87,7 @@ public class ParsedExpressionFunction extends ParsedExpression {
87 87
 		if (type instanceof FunctionTypeID) {
88 88
 			FunctionHeader definedHeader = header.compile(scope);
89 89
 			FunctionTypeID targetFunction = (FunctionTypeID) type;
90
-			return definedHeader.canCastTo(scope, targetFunction.header);
90
+			return definedHeader.canOverride(scope, targetFunction.header);
91 91
 		} else {
92 92
 			return false;
93 93
 		}

+ 11
- 1
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionVariable.java View File

@@ -26,6 +26,7 @@ import org.openzen.zenscript.codemodel.type.GenericName;
26 26
 import org.openzen.zenscript.codemodel.type.ITypeID;
27 27
 import org.openzen.zenscript.codemodel.type.member.TypeMembers;
28 28
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
29
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
29 30
 import org.openzen.zenscript.parser.ParsedAnnotation;
30 31
 import org.openzen.zenscript.parser.PrecompilationState;
31 32
 import org.openzen.zenscript.parser.definitions.ParsedFunctionHeader;
@@ -144,7 +145,16 @@ public class ParsedExpressionVariable extends ParsedExpression {
144 145
 			
145 146
 			throw new CompileException(position, CompileExceptionCode.UNDEFINED_VARIABLE, "No such symbol: " + name);
146 147
 		} else {
147
-			return result.eval().type;
148
+			if (result.getMember() != null) {
149
+				state.precompile(result.getMember());
150
+				result = scope.get(position, new GenericName(name, genericArguments));
151
+			}
152
+			
153
+			Expression resultExpression = result.eval();
154
+			if (resultExpression.type == BasicTypeID.UNDETERMINED)
155
+				System.out.println("Could not determine type");
156
+			
157
+			return resultExpression.type;
148 158
 		}
149 159
 	}
150 160
 }

+ 5
- 1
Parser/src/main/java/org/openzen/zenscript/parser/type/ParsedNamedType.java View File

@@ -46,7 +46,11 @@ public class ParsedNamedType implements IParsedType {
46 46
 		for (ParsedNamePart namePart : name)
47 47
 			genericNames.add(namePart.compile(scope));
48 48
 		
49
-		ITypeID result = scope.getTypeRegistry().getModified(modifiers, scope.getType(position, genericNames));
49
+		ITypeID baseType = scope.getType(position, genericNames);
50
+		if (baseType == null)
51
+			throw new CompileException(position, CompileExceptionCode.NO_SUCH_TYPE, "Type not found: " + toString());
52
+		
53
+		ITypeID result = scope.getTypeRegistry().getModified(modifiers, baseType);
50 54
 		if (result == null)
51 55
 			throw new CompileException(position, CompileExceptionCode.NO_SUCH_TYPE, "Type not found: " + toString());
52 56
 		

+ 2
- 0
ScriptingExample/scripts/ttt/helloworld.zs View File

@@ -3,3 +3,5 @@ println(5);
3 3
 println(2 + 5);
4 4
 println(1 - 2);
5 5
 println(1 + 3 as long);
6
+
7
+println(<hello world in bracket parser>);

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

@@ -8,6 +8,7 @@ import java.util.HashMap;
8 8
 import java.util.List;
9 9
 import java.util.Map;
10 10
 import java.util.Optional;
11
+import org.openzen.zencode.shared.CodePosition;
11 12
 import org.openzen.zencode.shared.SourceFile;
12 13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
13 14
 
@@ -22,7 +23,13 @@ import org.openzen.zenscript.formatter.ScriptFormattingSettings;
22 23
 import org.openzen.zenscript.javabytecode.JavaCompiler;
23 24
 import org.openzen.zenscript.javabytecode.JavaModule;
24 25
 import org.openzen.zenscript.codemodel.type.ISymbol;
26
+import org.openzen.zenscript.lexer.ZSToken;
27
+import org.openzen.zenscript.lexer.ZSTokenParser;
28
+import org.openzen.zenscript.lexer.ZSTokenType;
29
+import org.openzen.zenscript.parser.BracketExpressionParser;
25 30
 import org.openzen.zenscript.parser.ParsedFile;
31
+import org.openzen.zenscript.parser.expression.ParsedExpression;
32
+import org.openzen.zenscript.parser.expression.ParsedExpressionString;
26 33
 
27 34
 public class Main {
28 35
     /**
@@ -53,7 +60,7 @@ public class Main {
53 60
 	private static ParsedFile[] parse(ZSPackage pkg, File[] files) throws IOException {
54 61
 		ParsedFile[] parsedFiles = new ParsedFile[files.length];
55 62
 		for (int i = 0; i < files.length; i++) {
56
-			parsedFiles[i] = ParsedFile.parse(pkg, files[i]);
63
+			parsedFiles[i] = ParsedFile.parse(pkg, new TestBracketParser(), files[i]);
57 64
 		}
58 65
 		return parsedFiles;
59 66
 	}
@@ -158,4 +165,18 @@ public class Main {
158 165
 		}
159 166
 		return compiler.finishAndGetModule();
160 167
 	}
168
+	
169
+	private static class TestBracketParser implements BracketExpressionParser {
170
+		@Override
171
+		public ParsedExpression parse(CodePosition position, ZSTokenParser tokens) {
172
+			StringBuilder result = new StringBuilder();
173
+			while (tokens.optional(ZSTokenType.T_GREATER) == null) {
174
+				ZSToken token = tokens.next();
175
+				result.append(token.content);
176
+				result.append(tokens.getLastWhitespace());
177
+			}
178
+			
179
+			return new ParsedExpressionString(position.until(tokens.getPosition()), result.toString());
180
+		}
181
+	}
161 182
 }

+ 3
- 1
Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java View File

@@ -63,5 +63,7 @@ public enum CompileExceptionCode {
63 63
 	PRECOMPILE_FAILED,
64 64
 	UNTYPED_EMPTY_ARRAY,
65 65
 	UNTYPED_EMPTY_MAP,
66
-	VAR_WITHOUT_TYPE_OR_INITIALIZER
66
+	VAR_WITHOUT_TYPE_OR_INITIALIZER,
67
+	NO_BRACKET_PARSER,
68
+	INVALID_BRACKET_EXPRESSION
67 69
 }

+ 10
- 2
Shared/src/main/java/org/openzen/zencode/shared/FileSourceFile.java View File

@@ -6,12 +6,13 @@
6 6
 package org.openzen.zencode.shared;
7 7
 
8 8
 import java.io.BufferedInputStream;
9
-import java.io.BufferedReader;
9
+import java.io.BufferedOutputStream;
10 10
 import java.io.File;
11 11
 import java.io.FileInputStream;
12
-import java.io.FileReader;
12
+import java.io.FileOutputStream;
13 13
 import java.io.IOException;
14 14
 import java.io.InputStreamReader;
15
+import java.io.OutputStreamWriter;
15 16
 import java.io.Reader;
16 17
 import java.nio.charset.StandardCharsets;
17 18
 
@@ -39,4 +40,11 @@ public class FileSourceFile implements SourceFile {
39 40
 				new BufferedInputStream(new FileInputStream(file)),
40 41
 				StandardCharsets.UTF_8);
41 42
 	}
43
+
44
+	@Override
45
+	public void update(String content) throws IOException {
46
+		try (OutputStreamWriter writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file, false)), StandardCharsets.UTF_8)) {
47
+			writer.write(content);
48
+		}
49
+	}
42 50
 }

+ 5
- 0
Shared/src/main/java/org/openzen/zencode/shared/LiteralSourceFile.java View File

@@ -31,4 +31,9 @@ public class LiteralSourceFile implements SourceFile {
31 31
 	public Reader open() throws IOException {
32 32
 		return new StringReader(contents);
33 33
 	}
34
+
35
+	@Override
36
+	public void update(String content) throws IOException {
37
+		throw new UnsupportedOperationException("Cannot update literal source files");
38
+	}
34 39
 }

+ 2
- 0
Shared/src/main/java/org/openzen/zencode/shared/SourceFile.java View File

@@ -7,4 +7,6 @@ public interface SourceFile {
7 7
 	String getFilename();
8 8
 	
9 9
 	Reader open() throws IOException;
10
+	
11
+	void update(String content) throws IOException;
10 12
 }

+ 5
- 0
Shared/src/main/java/org/openzen/zencode/shared/VirtualSourceFile.java View File

@@ -28,4 +28,9 @@ public class VirtualSourceFile implements SourceFile {
28 28
 	public Reader open() throws IOException {
29 29
 		throw new UnsupportedOperationException("Cannot open virtual source files");
30 30
 	}
31
+
32
+	@Override
33
+	public void update(String content) throws IOException {
34
+		throw new UnsupportedOperationException("Cannot write to virtual source files");
35
+	}
31 36
 }

+ 1
- 1
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ValidationUtils.java View File

@@ -37,7 +37,7 @@ public class ValidationUtils {
37 37
 	private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z_0-9]*$");
38 38
 
39 39
 	public static void validateValidOverride(Validator target, CodePosition position, TypeScope scope, FunctionHeader header, FunctionHeader overridden) {
40
-		if (!header.canCastTo(scope, overridden))
40
+		if (!header.canOverride(scope, overridden))
41 41
 			target.logError(INVALID_OVERRIDE, position, "Invalid override: incompatible parameters or return type");
42 42
 	}
43 43
 	

Loading…
Cancel
Save