Browse Source

- Refactored horizontal and vertical layout in linear layout

- Added shape styling
- Minor code improvements and refactorings
Stan Hebben 6 years ago
parent
commit
ebe7df4449
33 changed files with 660 additions and 492 deletions
  1. 39
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/DPath.java
  2. 0
    282
      DrawableGui/src/main/java/org/openzen/drawablegui/layout/DHorizontalLayout.java
  3. 224
    74
      DrawableGui/src/main/java/org/openzen/drawablegui/layout/DLinearLayout.java
  4. 5
    8
      DrawableGui/src/main/java/org/openzen/drawablegui/layout/DLinearLayoutStyle.java
  5. 0
    36
      DrawableGui/src/main/java/org/openzen/drawablegui/layout/DVerticalLayoutStyle.java
  6. 5
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/live/SimpleLiveInt.java
  7. 27
    18
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java
  8. 3
    6
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPaneStyle.java
  9. 29
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DBaseStyle.java
  10. 5
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DEmptyStyleDefinition.java
  11. 10
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DMargin.java
  12. 23
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DRectangleShape.java
  13. 36
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DRoundedRectangleShape.java
  14. 17
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DShape.java
  15. 22
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DShapeElement.java
  16. 8
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DSimpleStylesheet.java
  17. 4
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DStyleClass.java
  18. 2
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DStyleDefinition.java
  19. 4
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DStyleElement.java
  20. 5
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/style/DStylesheetBuilder.java
  21. 3
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingRoot.java
  22. 1
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingWindow.java
  23. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/tree/DTreeViewStyle.java
  24. 15
    10
      IDE/src/main/java/org/openzen/zenscript/ide/ui/dialog/CreatePackageDialog.java
  25. 15
    10
      IDE/src/main/java/org/openzen/zenscript/ide/ui/dialog/CreateSourceFileDialog.java
  26. 3
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/StatusBarStyle.java
  27. 3
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/StatusBarView.java
  28. 7
    8
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedView.java
  29. 10
    18
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewStyle.java
  30. 5
    2
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/WindowView.java
  31. 65
    3
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputView.java
  32. 35
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/output/OutputViewStyle.java
  33. 29
    14
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/project/ProjectBrowser.java

+ 39
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/DPath.java View File

@@ -81,5 +81,44 @@ public interface DPath {
81 81
 		};
82 82
 	}
83 83
 	
84
+	public static DPath roundedRectangle(float x, float y, float width, float height, float radiusTopLeft, float radiusTopRight, float radiusBottomLeft, float radiusBottomRight) {
85
+		return tracer -> {
86
+			float cTopLeft = radiusTopLeft - radiusTopLeft * 0.551915024494f;
87
+			float cTopRight = radiusTopRight - radiusTopRight * 0.551915024494f;
88
+			float cBottomLeft = radiusBottomLeft - radiusBottomLeft * 0.551915024494f;
89
+			float cBottomRight = radiusBottomRight - radiusBottomRight * 0.551915024494f;
90
+			
91
+			tracer.moveTo(x + width - radiusBottomRight, y + height);
92
+			if (radiusBottomRight > 0.01f) {
93
+				tracer.bezierCubic(
94
+						x + width - cBottomRight, y + height,
95
+						x + width, y + height - cBottomRight,
96
+						x + width, y + height - radiusBottomRight);
97
+			}
98
+			tracer.lineTo(x + width, y + radiusTopRight);
99
+			if (radiusTopRight > 0.01f) {
100
+				tracer.bezierCubic(
101
+						x + width, y + cTopRight,
102
+						x + width - cTopRight, y,
103
+						x + width - radiusTopRight, y);
104
+			}
105
+			tracer.lineTo(x + radiusTopLeft, y);
106
+			if (radiusTopLeft > 0.01f) {
107
+				tracer.bezierCubic(
108
+						x + cTopLeft, y,
109
+						x, y + cTopLeft,
110
+						x, y + radiusTopLeft);
111
+			}
112
+			tracer.lineTo(x, y + height - radiusBottomLeft);
113
+			if (radiusBottomLeft > 0.01f) {
114
+				tracer.bezierCubic(
115
+						x, y + height - cBottomLeft,
116
+						x + cBottomLeft, y + height,
117
+						x + radiusBottomLeft, y + height);
118
+			}
119
+			tracer.close();
120
+		};
121
+	}
122
+	
84 123
 	void trace(DPathTracer tracer);
85 124
 }

+ 0
- 282
DrawableGui/src/main/java/org/openzen/drawablegui/layout/DHorizontalLayout.java View File

@@ -1,282 +0,0 @@
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.layout;
7
-
8
-import java.util.function.Consumer;
9
-import java.util.function.Predicate;
10
-import org.openzen.drawablegui.BaseComponentGroup;
11
-import org.openzen.drawablegui.DCanvas;
12
-import org.openzen.drawablegui.DComponent;
13
-import org.openzen.drawablegui.DIRectangle;
14
-import org.openzen.drawablegui.DSizing;
15
-import org.openzen.drawablegui.DUIContext;
16
-import org.openzen.drawablegui.listeners.ListenerHandle;
17
-import org.openzen.drawablegui.live.LiveObject;
18
-import org.openzen.drawablegui.live.MutableLiveObject;
19
-import org.openzen.drawablegui.style.DStyleClass;
20
-import org.openzen.drawablegui.style.DStylePath;
21
-
22
-/**
23
- *
24
- * @author Hoofdgebruiker
25
- */
26
-public class DHorizontalLayout extends BaseComponentGroup {
27
-	private final DStyleClass styleClass;
28
-	private final Alignment alignment;
29
-	private final Element[] components;
30
-	private final ListenerHandle<LiveObject.Listener<DSizing>>[] componentSizeListeners;
31
-	private final MutableLiveObject<DSizing> sizing = DSizing.create();
32
-	
33
-	private DUIContext context;
34
-	private DHorizontalLayoutStyle style;
35
-	private DIRectangle bounds;
36
-	private float totalGrow;
37
-	private float totalShrink;
38
-	
39
-	public DHorizontalLayout(DStyleClass styleClass, Alignment alignment, Element... components) {
40
-		this.styleClass = styleClass;
41
-		this.alignment = alignment;
42
-		this.components = components;
43
-		
44
-		componentSizeListeners = new ListenerHandle[components.length];
45
-		totalGrow = 0;
46
-		totalShrink = 0;
47
-		
48
-		for (int i = 0; i < componentSizeListeners.length; i++) {
49
-			componentSizeListeners[i] = components[i].component.getSizing().addListener((oldValue, newValue) -> updateDimensionPreferences());
50
-			
51
-			totalGrow += components[i].grow;
52
-			totalShrink += components[i].shrink;
53
-		}
54
-	}
55
-
56
-	@Override
57
-	protected void forEachChild(Consumer<DComponent> children) {
58
-		for (Element element : components)
59
-			children.accept(element.component);
60
-	}
61
-
62
-	@Override
63
-	protected DComponent findChild(Predicate<DComponent> predicate) {
64
-		for (Element element : components)
65
-			if (predicate.test(element.component))
66
-				return element.component;
67
-		
68
-		return null;
69
-	}
70
-
71
-	@Override
72
-	public void setContext(DStylePath parent, DUIContext context) {
73
-		this.context = context;
74
-		
75
-		DStylePath path = parent.getChild("horizontalLayout", styleClass);
76
-		style = new DHorizontalLayoutStyle(context.getStylesheets().get(context, path));
77
-		
78
-		for (Element element : components)
79
-			element.component.setContext(parent, context);
80
-		
81
-		layout();
82
-	}
83
-
84
-	@Override
85
-	public LiveObject<DSizing> getSizing() {
86
-		return sizing;
87
-	}
88
-
89
-	@Override
90
-	public DIRectangle getBounds() {
91
-		return bounds;
92
-	}
93
-
94
-	@Override
95
-	public int getBaselineY() {
96
-		return components[0].component.getBaselineY();
97
-	}
98
-
99
-	@Override
100
-	public void setBounds(DIRectangle bounds) {
101
-		this.bounds = bounds;
102
-		layout();
103
-	}
104
-
105
-	@Override
106
-	public void paint(DCanvas canvas) {
107
-		canvas.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height, style.backgroundColor);
108
-		style.border.paint(canvas, bounds);
109
-		for (Element element : components) {
110
-			element.component.paint(canvas);
111
-		}
112
-	}
113
-
114
-	@Override
115
-	public void close() {
116
-		for (int i = 0; i < componentSizeListeners.length; i++) {
117
-			componentSizeListeners[i].close();
118
-		}
119
-	}
120
-	
121
-	public static enum Alignment {
122
-		LEFT(0),
123
-		CENTER(0.5f),
124
-		RIGHT(1);
125
-		
126
-		public final float align;
127
-		
128
-		Alignment(float align) {
129
-			this.align = align;
130
-		}
131
-	}
132
-	
133
-	public static enum ElementAlignment {
134
-		TOP,
135
-		MIDDLE,
136
-		BOTTOM,
137
-		STRETCH
138
-	}
139
-	
140
-	public static class Element {
141
-		public final DComponent component;
142
-		public final float grow;
143
-		public final float shrink;
144
-		public final ElementAlignment alignment;
145
-		
146
-		public Element(DComponent component, float grow, float shrink, ElementAlignment alignment) {
147
-			this.component = component;
148
-			this.grow = grow;
149
-			this.shrink = shrink;
150
-			this.alignment = alignment;
151
-		}
152
-	}
153
-	
154
-	private void layout() {
155
-		if (bounds == null || context == null)
156
-			return;
157
-		
158
-		DSizing myPreferences = sizing.getValue();
159
-		if (bounds.width < myPreferences.preferredWidth) {
160
-			layoutShrinked();
161
-		} else {
162
-			layoutGrown();
163
-		}
164
-	}
165
-	
166
-	private void layoutShrinked() {
167
-		DSizing myPreferences = sizing.getValue();
168
-		if (totalShrink == 0) {
169
-			// now what?
170
-			// shrink proportionally, we have to shrink...
171
-			float scale = (float)(bounds.width - (components.length - 1) * style.spacing) / (myPreferences.preferredWidth - (components.length - 1) * style.spacing);
172
-			int x = 0;
173
-			
174
-			for (int i = 0; i < components.length; i++) {
175
-				Element element = components[i];
176
-				DSizing preferences = element.component.getSizing().getValue();
177
-				int newX = x + preferences.preferredWidth;
178
-				float idealUnspacedX = newX * scale;
179
-				int idealX = (int)(idealUnspacedX + 0.5f + i * style.spacing);
180
-				layout(element, x, idealX - x);
181
-				x = idealX;
182
-			}
183
-		} else {
184
-			int delta = bounds.width - myPreferences.preferredWidth;
185
-			float deltaScaled = delta / totalShrink;
186
-			int x = 0;
187
-			for (Element element : components) {
188
-				DSizing preferences = element.component.getSizing().getValue();
189
-				float scaledSize = preferences.preferredWidth + deltaScaled * element.shrink;
190
-				float idealUnspacedX = x + scaledSize;
191
-				int newX = (int)(idealUnspacedX + 0.5f);
192
-				layout(element, x, newX - x);
193
-				x = newX + style.spacing;
194
-			}
195
-		}
196
-	}
197
-	
198
-	private void layoutGrown() {
199
-		// resize according to grow values
200
-		DSizing myPreferences = sizing.getValue();
201
-		
202
-		if (totalGrow == 0) {
203
-			int deltaX = (int)(myPreferences.preferredWidth - bounds.width);
204
-			int x = bounds.x + (int)(deltaX * alignment.align);
205
-			for (Element element : components) {
206
-				DSizing preferences = element.component.getSizing().getValue();
207
-				int newX = x + preferences.preferredWidth;
208
-				layout(element, x, newX - x);
209
-				x = newX + style.spacing;
210
-			}
211
-		} else {
212
-			int delta = bounds.width - myPreferences.preferredWidth;
213
-			float deltaScaled = delta / totalGrow;
214
-			int x = 0;
215
-			for (Element element : components) {
216
-				DSizing preferences = element.component.getSizing().getValue();
217
-				float scaledSize = preferences.preferredWidth + deltaScaled * element.grow;
218
-				float idealUnspacedX = x + scaledSize;
219
-				int newX = (int)(idealUnspacedX + 0.5f);
220
-				layout(element, x, newX - x);
221
-				x = newX + style.spacing;
222
-			}
223
-		}
224
-	}
225
-	
226
-	private void layout(Element element, int x, int width) {
227
-		DSizing preferences = element.component.getSizing().getValue();
228
-		int height;
229
-		int y;
230
-		switch (element.alignment) {
231
-			case BOTTOM:
232
-				height = Math.min(preferences.preferredHeight, bounds.height - style.border.getPaddingVertical());
233
-				y = bounds.y + style.border.getPaddingTop();
234
-				break;
235
-			case MIDDLE:
236
-				height = Math.min(preferences.preferredHeight, bounds.height - style.border.getPaddingVertical());
237
-				y = bounds.y + style.border.getPaddingTop() + (bounds.height - style.border.getPaddingVertical() - height) / 2;
238
-				break;
239
-			case TOP:
240
-				height = Math.min(preferences.preferredHeight, bounds.height - style.border.getPaddingVertical());
241
-				y = bounds.y + bounds.height - style.border.getPaddingBottom() - height;
242
-				break;
243
-			case STRETCH:
244
-			default:
245
-				height = bounds.height - style.border.getPaddingVertical();
246
-				y = bounds.y + style.border.getPaddingTop();
247
-				break;
248
-		}
249
-		element.component.setBounds(new DIRectangle(x, y, width, height));
250
-	}
251
-	
252
-	private void updateDimensionPreferences() {
253
-		int preferredWidth = -style.spacing;
254
-		int preferredHeight = 0;
255
-		int minimumWidth = -style.spacing;
256
-		int minimumHeight = 0;
257
-		int maximumWidth = -style.spacing;
258
-		int maximumHeight = Integer.MAX_VALUE;
259
-		for (Element element : components) {
260
-			DSizing preferences = element.component.getSizing().getValue();
261
-			preferredWidth += preferences.preferredWidth + style.spacing;
262
-			preferredHeight = Math.max(preferredHeight, preferences.preferredHeight);
263
-			
264
-			minimumWidth += preferences.minimumWidth + style.spacing;
265
-			minimumHeight = Math.max(minimumHeight, preferences.minimumHeight);
266
-			
267
-			maximumWidth += preferences.maximumWidth + style.spacing;
268
-			maximumHeight = Math.min(maximumHeight, preferences.maximumHeight);
269
-		}
270
-		
271
-		int paddingHorizontal = style.border.getPaddingHorizontal();
272
-		int paddingVertical = style.border.getPaddingVertical();
273
-		DSizing preferences = new DSizing(
274
-				minimumWidth + paddingHorizontal,
275
-				minimumHeight + paddingVertical,
276
-				preferredWidth + paddingHorizontal,
277
-				preferredHeight + paddingVertical,
278
-				maximumWidth + paddingHorizontal,
279
-				maximumHeight + paddingVertical);
280
-		sizing.setValue(preferences);
281
-	}
282
-}

DrawableGui/src/main/java/org/openzen/drawablegui/layout/DVerticalLayout.java → DrawableGui/src/main/java/org/openzen/drawablegui/layout/DLinearLayout.java View File

@@ -25,22 +25,24 @@ import org.openzen.drawablegui.style.DStylePath;
25 25
  *
26 26
  * @author Hoofdgebruiker
27 27
  */
28
-public class DVerticalLayout extends BaseComponentGroup {
28
+public class DLinearLayout extends BaseComponentGroup {
29 29
 	private final DStyleClass styleClass;
30
+	private final Orientation orientation;
30 31
 	private final Alignment alignment;
31 32
 	private final Element[] components;
32 33
 	private final ListenerHandle<LiveObject.Listener<DSizing>>[] componentSizeListeners;
33 34
 	private final MutableLiveObject<DSizing> sizing = DSizing.create();
34 35
 	
35 36
 	private DUIContext context;
36
-	private DVerticalLayoutStyle style;
37
+	private DLinearLayoutStyle style;
37 38
 	private DIRectangle bounds;
38 39
 	private float totalGrow;
39 40
 	private float totalShrink;
40 41
 	private DPath shape;
41 42
 	
42
-	public DVerticalLayout(DStyleClass styleClass, Alignment alignment, Element... components) {
43
+	public DLinearLayout(DStyleClass styleClass, Orientation orientation, Alignment alignment, Element... components) {
43 44
 		this.styleClass = styleClass;
45
+		this.orientation = orientation;
44 46
 		this.alignment = alignment;
45 47
 		this.components = components;
46 48
 		
@@ -49,7 +51,7 @@ public class DVerticalLayout extends BaseComponentGroup {
49 51
 		totalShrink = 0;
50 52
 		
51 53
 		for (int i = 0; i < componentSizeListeners.length; i++) {
52
-			componentSizeListeners[i] = components[i].component.getSizing().addListener((oldValue, newValue) -> updateDimensionPreferences());
54
+			componentSizeListeners[i] = components[i].component.getSizing().addListener((oldValue, newValue) -> updateSizing());
53 55
 			
54 56
 			totalGrow += components[i].grow;
55 57
 			totalShrink += components[i].shrink;
@@ -76,7 +78,7 @@ public class DVerticalLayout extends BaseComponentGroup {
76 78
 		this.context = context;
77 79
 		
78 80
 		DStylePath path = parent.getChild("verticalLayout", styleClass);
79
-		style = new DVerticalLayoutStyle(context.getStylesheets().get(context, path));
81
+		style = new DLinearLayoutStyle(context.getStylesheets().get(context, path));
80 82
 		
81 83
 		for (Element element : components)
82 84
 			element.component.setContext(parent, context);
@@ -100,18 +102,14 @@ public class DVerticalLayout extends BaseComponentGroup {
100 102
 	@Override
101 103
 	public void setBounds(DIRectangle bounds) {
102 104
 		this.bounds = bounds;
103
-		shape = DPath.roundedRectangle(
104
-				bounds.x + style.margin.left,
105
-				bounds.y + style.margin.top,
106
-				bounds.width - style.margin.getHorizontal(),
107
-				bounds.height - style.margin.getVertical(),
108
-				style.cornerRadius);
105
+		shape = style.shape.instance(style.margin.apply(bounds));
109 106
 		layout();
110 107
 	}
111 108
 
112 109
 	@Override
113 110
 	public void paint(DCanvas canvas) {
114 111
 		canvas.shadowPath(shape, DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
112
+		style.border.paint(canvas, bounds);
115 113
 		for (Element element : components) {
116 114
 			element.component.paint(canvas);
117 115
 		}
@@ -124,85 +122,103 @@ public class DVerticalLayout extends BaseComponentGroup {
124 122
 		}
125 123
 	}
126 124
 	
127
-	public static enum Alignment {
128
-		TOP(0),
129
-		MIDDLE(0.5f),
130
-		BOTTOM(1);
131
-		
132
-		public final float align;
133
-		
134
-		Alignment(float align) {
135
-			this.align = align;
136
-		}
125
+	private int getInnerWidth() {
126
+		return bounds.width - style.margin.getHorizontal() - style.border.getPaddingHorizontal();
137 127
 	}
138 128
 	
139
-	public static enum ElementAlignment {
140
-		LEFT,
141
-		CENTER,
142
-		RIGHT,
143
-		STRETCH
129
+	private int getInnerHeight() {
130
+		return bounds.height - style.margin.getVertical() - style.border.getPaddingVertical();
144 131
 	}
145 132
 	
146
-	public static class Element {
147
-		public final DComponent component;
148
-		public final float grow;
149
-		public final float shrink;
150
-		public final ElementAlignment alignment;
151
-		
152
-		public Element(DComponent component, float grow, float shrink, ElementAlignment alignment) {
153
-			this.component = component;
154
-			this.grow = grow;
155
-			this.shrink = shrink;
156
-			this.alignment = alignment;
157
-		}
133
+	private int getPreferredInnerWidth() {
134
+		DSizing myPreferences = sizing.getValue();
135
+		return myPreferences.preferredWidth - style.margin.getHorizontal() - style.border.getPaddingHorizontal();
136
+	}
137
+	
138
+	private int getPreferredInnerHeight() {
139
+		DSizing myPreferences = sizing.getValue();
140
+		return myPreferences.preferredHeight - style.margin.getVertical() - style.border.getPaddingVertical();
158 141
 	}
159 142
 	
160 143
 	private void layout() {
144
+		if (orientation == Orientation.HORIZONTAL) {
145
+			layoutHorizontal();
146
+		} else {
147
+			layoutVertical();
148
+		}
149
+	}
150
+	
151
+	private void layoutHorizontal() {
161 152
 		if (bounds == null || context == null)
162 153
 			return;
163 154
 		
164 155
 		DSizing myPreferences = sizing.getValue();
165
-		if (bounds.height < myPreferences.preferredHeight) {
166
-			layoutShrinked();
156
+		if (bounds.width < myPreferences.preferredWidth) {
157
+			layoutHorizontalShrinked();
167 158
 		} else {
168
-			layoutGrown();
159
+			layoutHorizontalGrown();
169 160
 		}
170 161
 	}
171 162
 	
172
-	private int getInnerWidth() {
173
-		return bounds.width - style.margin.getHorizontal() - style.border.getPaddingHorizontal();
174
-	}
175
-	
176
-	private int getInnerHeight() {
177
-		return bounds.height - style.margin.getVertical() - style.border.getPaddingVertical();
178
-	}
179
-	
180
-	private int getPreferredInnerWidth() {
163
+	private void layoutVertical() {
164
+		if (bounds == null || context == null)
165
+			return;
166
+		
181 167
 		DSizing myPreferences = sizing.getValue();
182
-		return myPreferences.preferredWidth - style.margin.getHorizontal() - style.border.getPaddingHorizontal();
168
+		if (bounds.height < myPreferences.preferredHeight) {
169
+			layoutVerticalShrinked();
170
+		} else {
171
+			layoutVerticalGrown();
172
+		}
183 173
 	}
184 174
 	
185
-	private int getPreferredInnerHeight() {
186
-		DSizing myPreferences = sizing.getValue();
187
-		return myPreferences.preferredHeight - style.margin.getVertical() - style.border.getPaddingVertical();
175
+	private void layoutHorizontalShrinked() {
176
+		float availableWidth = getInnerWidth() - (components.length - 1) * style.spacing;
177
+		float preferredInnerWidth = getPreferredInnerWidth() - (components.length - 1) * style.spacing;
178
+		
179
+		if (totalShrink == 0) {
180
+			// now what?
181
+			// shrink proportionally, we have to shrink...
182
+			float scale = availableWidth / preferredInnerWidth;
183
+			int x = bounds.x + style.margin.left + style.border.getPaddingLeft();
184
+			
185
+			for (Element element : components) {
186
+				DSizing preferences = element.component.getSizing().getValue();
187
+				int newX = (int)(x + preferences.preferredWidth * scale + 0.5f);
188
+				layoutHorizontal(element, bounds.x + x, newX - x);
189
+				x = newX + style.spacing;
190
+			}
191
+		} else {
192
+			int delta = getInnerHeight() - getPreferredInnerHeight();
193
+			float deltaScaled = delta / totalShrink;
194
+			int y = bounds.y;
195
+			for (Element element : components) {
196
+				DSizing preferences = element.component.getSizing().getValue();
197
+				float scaledSize = preferences.preferredHeight + deltaScaled * element.shrink;
198
+				float idealUnspacedY = y + scaledSize;
199
+				int newX = (int)(idealUnspacedY + 0.5f);
200
+				layoutHorizontal(element, y, newX - y);
201
+				y = newX + style.spacing;
202
+			}
203
+		}
188 204
 	}
189 205
 	
190
-	private void layoutShrinked() {
206
+	private void layoutVerticalShrinked() {
207
+		float availableHeight = getInnerHeight() - (components.length - 1) * style.spacing;
208
+		float preferredInnerHeight = getPreferredInnerHeight() - (components.length - 1) * style.spacing;
209
+		
191 210
 		if (totalShrink == 0) {
192 211
 			// now what?
193 212
 			// shrink proportionally, we have to shrink...
194
-			float availableHeight = getInnerHeight() - (components.length - 1) * style.spacing;
195
-			float scale = (float)(availableHeight) / (getPreferredInnerHeight() - (components.length - 1) * style.spacing);
213
+			float scale = availableHeight / preferredInnerHeight;
196 214
 			int y = bounds.y + style.margin.top + style.border.getPaddingTop();
197 215
 			
198 216
 			for (int i = 0; i < components.length; i++) {
199 217
 				Element element = components[i];
200 218
 				DSizing preferences = element.component.getSizing().getValue();
201
-				int newY = y + preferences.preferredHeight;
202
-				float idealUnspacedY = newY * scale;
203
-				int idealY = (int)(idealUnspacedY + 0.5f + i * style.spacing);
204
-				layout(element, bounds.y + y, idealY - y);
205
-				y = idealY;
219
+				int newY = (int)(y + preferences.preferredHeight * scale + 0.5f);
220
+				layoutVertical(element, bounds.y + y, newY - y);
221
+				y = newY + style.spacing;
206 222
 			}
207 223
 		} else {
208 224
 			int delta = getInnerHeight() - getPreferredInnerHeight();
@@ -213,39 +229,89 @@ public class DVerticalLayout extends BaseComponentGroup {
213 229
 				float scaledSize = preferences.preferredHeight + deltaScaled * element.shrink;
214 230
 				float idealUnspacedY = y + scaledSize;
215 231
 				int newY = (int)(idealUnspacedY + 0.5f);
216
-				layout(element, y, newY - y);
232
+				layoutVertical(element, y, newY - y);
217 233
 				y = newY + style.spacing;
218 234
 			}
219 235
 		}
220 236
 	}
221 237
 	
222
-	private void layoutGrown() {
238
+	private void layoutHorizontalGrown() {
223 239
 		// resize according to grow values
240
+		int delta = getPreferredInnerWidth() - getInnerWidth();
224 241
 		if (totalGrow == 0) {
225
-			int deltaY = getPreferredInnerHeight() - getInnerHeight();
226
-			int y = bounds.y + style.margin.top + style.border.getPaddingTop() + (int)(deltaY * alignment.align);
242
+			int x = bounds.x + style.margin.left + style.border.getPaddingLeft() + (int)(delta * alignment.align);
243
+			for (Element element : components) {
244
+				DSizing preferences = element.component.getSizing().getValue();
245
+				int newX = x + preferences.preferredWidth;
246
+				layoutHorizontal(element, x, newX - x);
247
+				x = newX;
248
+			}
249
+		} else {
250
+			float deltaScaled = delta / totalGrow;
251
+			int x = bounds.x + style.margin.left + style.border.getPaddingLeft();
252
+			for (Element element : components) {
253
+				DSizing preferences = element.component.getSizing().getValue();
254
+				float scaledSize = preferences.preferredWidth - deltaScaled * element.grow;
255
+				float idealUnspacedX = x + scaledSize;
256
+				int newX = (int)(idealUnspacedX + 0.5f);
257
+				layoutHorizontal(element, x, newX - x);
258
+				x = newX + style.spacing;
259
+			}
260
+		}
261
+	}
262
+	
263
+	private void layoutVerticalGrown() {
264
+		// resize according to grow values
265
+		int delta = getPreferredInnerHeight() - getInnerHeight();
266
+		if (totalGrow == 0) {
267
+			int y = bounds.y + style.margin.top + style.border.getPaddingTop() + (int)(delta * alignment.align);
227 268
 			for (Element element : components) {
228 269
 				DSizing preferences = element.component.getSizing().getValue();
229 270
 				int newY = y + preferences.preferredHeight;
230
-				layout(element, y, newY - y);
271
+				layoutVertical(element, y, newY - y);
231 272
 				y = newY;
232 273
 			}
233 274
 		} else {
234
-			int delta = getPreferredInnerHeight() - getInnerHeight();
235 275
 			float deltaScaled = delta / totalGrow;
236 276
 			int y = bounds.y + style.margin.top + style.border.getPaddingTop();
237 277
 			for (Element element : components) {
238 278
 				DSizing preferences = element.component.getSizing().getValue();
239
-				float scaledSize = preferences.preferredHeight + deltaScaled * element.grow;
279
+				float scaledSize = preferences.preferredHeight - deltaScaled * element.grow;
240 280
 				float idealUnspacedY = y + scaledSize;
241 281
 				int newY = (int)(idealUnspacedY + 0.5f);
242
-				layout(element, y, newY - y);
282
+				layoutVertical(element, y, newY - y);
243 283
 				y = newY + style.spacing;
244 284
 			}
245 285
 		}
246 286
 	}
247 287
 	
248
-	private void layout(Element element, int y, int height) {
288
+	private void layoutHorizontal(Element element, int x, int width) {
289
+		DSizing preferences = element.component.getSizing().getValue();
290
+		int height;
291
+		int y;
292
+		switch (element.alignment) {
293
+			case BOTTOM:
294
+				height = Math.min(preferences.preferredHeight, bounds.height - style.border.getPaddingVertical());
295
+				y = bounds.y + style.border.getPaddingTop();
296
+				break;
297
+			case MIDDLE:
298
+				height = Math.min(preferences.preferredHeight, bounds.height - style.border.getPaddingVertical());
299
+				y = bounds.y + style.border.getPaddingTop() + (bounds.height - style.border.getPaddingVertical() - height) / 2;
300
+				break;
301
+			case TOP:
302
+				height = Math.min(preferences.preferredHeight, bounds.height - style.border.getPaddingVertical());
303
+				y = bounds.y + bounds.height - style.border.getPaddingBottom() - height;
304
+				break;
305
+			case STRETCH:
306
+			default:
307
+				height = bounds.height - style.border.getPaddingVertical();
308
+				y = bounds.y + style.border.getPaddingTop();
309
+				break;
310
+		}
311
+		element.component.setBounds(new DIRectangle(x, y, width, height));
312
+	}
313
+	
314
+	private void layoutVertical(Element element, int y, int height) {
249 315
 		DSizing preferences = element.component.getSizing().getValue();
250 316
 		int x;
251 317
 		int width;
@@ -271,7 +337,47 @@ public class DVerticalLayout extends BaseComponentGroup {
271 337
 		element.component.setBounds(new DIRectangle(x, y, width, height));
272 338
 	}
273 339
 	
274
-	private void updateDimensionPreferences() {
340
+	private void updateSizing() {
341
+		if (orientation == Orientation.HORIZONTAL) {
342
+			updateSizingHorizontal();
343
+		} else {
344
+			updateSizingVertical();
345
+		}
346
+	}
347
+	
348
+	private void updateSizingHorizontal() {
349
+		int preferredWidth = -style.spacing;
350
+		int preferredHeight = 0;
351
+		int minimumWidth = -style.spacing;
352
+		int minimumHeight = Integer.MAX_VALUE;
353
+		int maximumWidth = -style.spacing;
354
+		int maximumHeight = 0;
355
+		
356
+		for (Element element : components) {
357
+			DSizing preferences = element.component.getSizing().getValue();
358
+			preferredWidth += preferences.preferredWidth + style.spacing;
359
+			preferredHeight = Math.max(preferredHeight, preferences.preferredHeight);
360
+			
361
+			minimumWidth += preferences.minimumWidth + style.spacing;
362
+			minimumHeight = Math.max(minimumHeight, preferences.minimumHeight);
363
+			
364
+			maximumHeight += preferences.maximumWidth + style.spacing;
365
+			maximumWidth = Math.min(maximumHeight, preferences.maximumHeight);
366
+		}
367
+		
368
+		int paddingHorizontal = style.border.getPaddingHorizontal() + style.margin.getHorizontal();
369
+		int paddingVertical = style.border.getPaddingVertical() + style.margin.getVertical();
370
+		DSizing preferences = new DSizing(
371
+				minimumWidth + paddingHorizontal,
372
+				minimumHeight + paddingVertical,
373
+				preferredWidth + paddingHorizontal,
374
+				preferredHeight + paddingVertical,
375
+				maximumWidth + paddingHorizontal,
376
+				maximumHeight + paddingVertical);
377
+		sizing.setValue(preferences);
378
+	}
379
+	
380
+	private void updateSizingVertical() {
275 381
 		int preferredWidth = 0;
276 382
 		int preferredHeight = -style.spacing;
277 383
 		int minimumWidth = 0;
@@ -291,8 +397,8 @@ public class DVerticalLayout extends BaseComponentGroup {
291 397
 			maximumHeight += preferences.maximumHeight + style.spacing;
292 398
 		}
293 399
 		
294
-		int paddingHorizontal = style.border.getPaddingHorizontal();
295
-		int paddingVertical = style.border.getPaddingVertical();
400
+		int paddingHorizontal = style.border.getPaddingHorizontal() + style.margin.getHorizontal();
401
+		int paddingVertical = style.border.getPaddingVertical() + style.margin.getVertical();
296 402
 		DSizing preferences = new DSizing(
297 403
 				minimumWidth + paddingHorizontal,
298 404
 				minimumHeight + paddingVertical,
@@ -302,4 +408,48 @@ public class DVerticalLayout extends BaseComponentGroup {
302 408
 				maximumHeight + paddingVertical);
303 409
 		sizing.setValue(preferences);
304 410
 	}
411
+	
412
+	public static enum Orientation {
413
+		HORIZONTAL,
414
+		VERTICAL
415
+	}
416
+	
417
+	public static enum Alignment {
418
+		TOP(0),
419
+		LEFT(0),
420
+		MIDDLE(0.5f),
421
+		CENTER(0.5f),
422
+		BOTTOM(1),
423
+		RIGHT(1);
424
+		
425
+		public final float align;
426
+		
427
+		Alignment(float align) {
428
+			this.align = align;
429
+		}
430
+	}
431
+	
432
+	public static enum ElementAlignment {
433
+		LEFT,
434
+		CENTER,
435
+		RIGHT,
436
+		TOP,
437
+		MIDDLE,
438
+		BOTTOM,
439
+		STRETCH
440
+	}
441
+	
442
+	public static class Element {
443
+		public final DComponent component;
444
+		public final float grow;
445
+		public final float shrink;
446
+		public final ElementAlignment alignment;
447
+		
448
+		public Element(DComponent component, float grow, float shrink, ElementAlignment alignment) {
449
+			this.component = component;
450
+			this.grow = grow;
451
+			this.shrink = shrink;
452
+			this.alignment = alignment;
453
+		}
454
+	}
305 455
 }

DrawableGui/src/main/java/org/openzen/drawablegui/layout/DHorizontalLayoutStyle.java → DrawableGui/src/main/java/org/openzen/drawablegui/layout/DLinearLayoutStyle.java View File

@@ -5,8 +5,7 @@
5 5
  */
6 6
 package org.openzen.drawablegui.layout;
7 7
 
8
-import org.openzen.drawablegui.border.DBorder;
9
-import org.openzen.drawablegui.border.DPaddedBorder;
8
+import org.openzen.drawablegui.style.DBaseStyle;
10 9
 import org.openzen.drawablegui.style.DDpDimension;
11 10
 import org.openzen.drawablegui.style.DStyleDefinition;
12 11
 
@@ -14,14 +13,12 @@ import org.openzen.drawablegui.style.DStyleDefinition;
14 13
  *
15 14
  * @author Hoofdgebruiker
16 15
  */
17
-public class DHorizontalLayoutStyle {
16
+public class DLinearLayoutStyle extends DBaseStyle {
18 17
 	public final int spacing;
19
-	public final DBorder border;
20
-	public final int backgroundColor;
21 18
 	
22
-	public DHorizontalLayoutStyle(DStyleDefinition style) {
19
+	public DLinearLayoutStyle(DStyleDefinition style) {
20
+		super(style);
21
+		
23 22
 		spacing = style.getDimension("spacing", new DDpDimension(8));
24
-		border = style.getBorder("border", context -> new DPaddedBorder(context.dp(8)));
25
-		backgroundColor = style.getColor("backgroundColor", 0);
26 23
 	}
27 24
 }

+ 0
- 36
DrawableGui/src/main/java/org/openzen/drawablegui/layout/DVerticalLayoutStyle.java View File

@@ -1,36 +0,0 @@
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.layout;
7
-
8
-import org.openzen.drawablegui.border.DBorder;
9
-import org.openzen.drawablegui.border.DPaddedBorder;
10
-import org.openzen.drawablegui.style.DDpDimension;
11
-import org.openzen.drawablegui.style.DMargin;
12
-import org.openzen.drawablegui.style.DPxDimension;
13
-import org.openzen.drawablegui.style.DShadow;
14
-import org.openzen.drawablegui.style.DStyleDefinition;
15
-
16
-/**
17
- *
18
- * @author Hoofdgebruiker
19
- */
20
-public class DVerticalLayoutStyle {
21
-	public final int spacing;
22
-	public final DBorder border;
23
-	public final int backgroundColor;
24
-	public final DMargin margin;
25
-	public final int cornerRadius;
26
-	public final DShadow shadow;
27
-	
28
-	public DVerticalLayoutStyle(DStyleDefinition style) {
29
-		spacing = style.getDimension("spacing", new DDpDimension(8));
30
-		border = style.getBorder("border", context -> new DPaddedBorder(context.dp(8)));
31
-		backgroundColor = style.getColor("backgroundColor", 0);
32
-		margin = style.getMargin("margin", DMargin.EMPTY_ELEMENT);
33
-		cornerRadius = style.getDimension("cornerRadius", DPxDimension.ZERO);
34
-		shadow = style.getShadow("shadow", DShadow.NONE_ELEMENT);
35
-	}
36
-}

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

@@ -14,8 +14,12 @@ import org.openzen.drawablegui.listeners.ListenerList;
14 14
  */
15 15
 public class SimpleLiveInt implements LiveInt {
16 16
 	private final ListenerList<Listener> listeners = new ListenerList<>();
17
-	private int value = 0;
17
+	private int value;
18 18
 
19
+	public SimpleLiveInt(int value) {
20
+		this.value = value;
21
+	}
22
+	
19 23
 	@Override
20 24
 	public int getValue() {
21 25
 		return value;

+ 27
- 18
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java View File

@@ -14,13 +14,16 @@ import org.openzen.drawablegui.DFont;
14 14
 import org.openzen.drawablegui.DFontMetrics;
15 15
 import org.openzen.drawablegui.DIRectangle;
16 16
 import org.openzen.drawablegui.DMouseEvent;
17
+import org.openzen.drawablegui.DPath;
17 18
 import org.openzen.drawablegui.DTimerHandle;
19
+import org.openzen.drawablegui.DTransform2D;
18 20
 import org.openzen.drawablegui.listeners.ListenerHandle;
19 21
 import org.openzen.drawablegui.live.LiveInt;
20 22
 import org.openzen.drawablegui.live.LiveObject;
21 23
 import org.openzen.drawablegui.live.SimpleLiveInt;
22 24
 import org.openzen.drawablegui.DUIContext;
23 25
 import org.openzen.drawablegui.DUIWindow;
26
+import org.openzen.drawablegui.live.MutableLiveObject;
24 27
 import org.openzen.drawablegui.style.DStyleClass;
25 28
 import org.openzen.drawablegui.style.DStylePath;
26 29
 import org.openzen.drawablegui.style.DStyleSheets;
@@ -37,23 +40,30 @@ public class DScrollPane implements DComponent {
37 40
 	private DIRectangle bounds;
38 41
 	
39 42
 	private DScrollPaneStyle style;
43
+	private DPath shape;
40 44
 	private final LiveInt contentsHeight;
41 45
 	private final LiveInt offsetX;
42 46
 	private final LiveInt offsetY;
43 47
 	
48
+	private final LiveInt preferredHeight;
49
+	private final MutableLiveObject<DSizing> sizing = DSizing.create();
50
+	
44 51
 	private final ListenerHandle<LiveInt.Listener> contentsHeightListener;
45 52
 	private final ListenerHandle<LiveInt.Listener> offsetXListener;
46 53
 	private final ListenerHandle<LiveInt.Listener> offsetYListener;
54
+	private final ListenerHandle<LiveInt.Listener> preferredHeightListener;
55
+	private final ListenerHandle<LiveObject.Listener<DSizing>> contentsSizingListener;
47 56
 	
48 57
 	private DComponent hovering = null;
49 58
 	
50
-	public DScrollPane(DStyleClass styleClass, DComponent contents) {
59
+	public DScrollPane(DStyleClass styleClass, DComponent contents, LiveInt preferredHeight) {
51 60
 		this.styleClass = styleClass;
52 61
 		this.contents = contents;
62
+		this.preferredHeight = preferredHeight;
53 63
 		
54
-		contentsHeight = new SimpleLiveInt();
55
-		offsetX = new SimpleLiveInt();
56
-		offsetY = new SimpleLiveInt();
64
+		contentsHeight = new SimpleLiveInt(0);
65
+		offsetX = new SimpleLiveInt(0);
66
+		offsetY = new SimpleLiveInt(0);
57 67
 		
58 68
 		scrollBar = new DScrollBar(DStyleClass.EMPTY, contentsHeight, offsetY);
59 69
 		
@@ -68,6 +78,12 @@ public class DScrollPane implements DComponent {
68 78
 			contents.setBounds(new DIRectangle(0, 0, bounds.width, Math.max(bounds.height, newPreferences.preferredHeight)));
69 79
 			contentsHeight.setValue(newPreferences.preferredHeight);
70 80
 		});
81
+		preferredHeightListener = preferredHeight.addListener((oldValue, newValue) -> {
82
+			sizing.setValue(new DSizing(contents.getSizing().getValue().preferredWidth, newValue));
83
+		});
84
+		contentsSizingListener = contents.getSizing().addListener((oldValue, newValue) -> {
85
+			sizing.setValue(new DSizing(newValue.preferredWidth, preferredHeight.getValue()));
86
+		});
71 87
 	}
72 88
 	
73 89
 	@Override
@@ -88,14 +104,11 @@ public class DScrollPane implements DComponent {
88 104
 		contents.setContext(path, new TranslatedContext());
89 105
 		scrollBar.setContext(path, context);
90 106
 		style = new DScrollPaneStyle(context.getStylesheets().get(context, path));
91
-		
92
-		if (bounds != null)
93
-			setBounds(bounds);
94 107
 	}
95 108
 
96 109
 	@Override
97 110
 	public LiveObject<DSizing> getSizing() {
98
-		return contents.getSizing(); // TODO: derived preferences
111
+		return sizing;
99 112
 	}
100 113
 
101 114
 	@Override
@@ -111,28 +124,24 @@ public class DScrollPane implements DComponent {
111 124
 	@Override
112 125
 	public void setBounds(DIRectangle bounds) {
113 126
 		this.bounds = bounds;
114
-		
115
-		if (this.context == null)
116
-			return;
127
+		shape = style.shape.instance(style.margin.apply(bounds));
117 128
 		
118 129
 		int height = Math.max(bounds.height - style.border.getPaddingTop() - style.border.getPaddingBottom(),
119 130
 				contents.getSizing().getValue().preferredHeight);
120 131
 		int scrollBarWidth = scrollBar.getSizing().getValue().preferredWidth;
121 132
 		scrollBar.setBounds(new DIRectangle(
122
-				bounds.x + bounds.width - scrollBarWidth - style.border.getPaddingRight(),
123
-				bounds.y + style.border.getPaddingTop(),
133
+				bounds.x + bounds.width - scrollBarWidth - style.border.getPaddingRight() - style.margin.right,
134
+				bounds.y + style.border.getPaddingTop() + style.margin.top,
124 135
 				scrollBarWidth,
125
-				bounds.height - style.border.getPaddingTop() - style.border.getPaddingBottom()));
136
+				bounds.height - style.border.getPaddingVertical() - style.margin.getVertical()));
126 137
 		contents.setBounds(new DIRectangle(0, 0, bounds.width - scrollBar.getBounds().width, height));
127 138
 		contentsHeight.setValue(height);
128 139
 	}
129 140
 
130 141
 	@Override
131 142
 	public void paint(DCanvas canvas) {
132
-		if (bounds == null)
133
-			return;
134
-		
135
-		style.border.paint(canvas, bounds);
143
+		canvas.shadowPath(shape, DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
144
+		style.border.paint(canvas, style.margin.apply(bounds));
136 145
 		scrollBar.paint(canvas);
137 146
 		
138 147
 		canvas.pushBounds(new DIRectangle(

+ 3
- 6
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPaneStyle.java View File

@@ -5,18 +5,15 @@
5 5
  */
6 6
 package org.openzen.drawablegui.scroll;
7 7
 
8
-import org.openzen.drawablegui.border.DBorder;
9
-import org.openzen.drawablegui.border.DLineBorder;
8
+import org.openzen.drawablegui.style.DBaseStyle;
10 9
 import org.openzen.drawablegui.style.DStyleDefinition;
11 10
 
12 11
 /**
13 12
  *
14 13
  * @author Hoofdgebruiker
15 14
  */
16
-public class DScrollPaneStyle {
17
-	public final DBorder border;
18
-	
15
+public class DScrollPaneStyle extends DBaseStyle {
19 16
 	public DScrollPaneStyle(DStyleDefinition style) {
20
-		this.border = style.getBorder("border", context -> new DLineBorder(0xFF888888, 1));
17
+		super(style);
21 18
 	}
22 19
 }

+ 29
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DBaseStyle.java View File

@@ -0,0 +1,29 @@
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.style;
7
+
8
+import org.openzen.drawablegui.border.DBorder;
9
+import org.openzen.drawablegui.border.DEmptyBorder;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class DBaseStyle {
16
+	public final DMargin margin;
17
+	public final DBorder border;
18
+	public final DShadow shadow;
19
+	public final DShape shape;
20
+	public final int backgroundColor;
21
+	
22
+	public DBaseStyle(DStyleDefinition style) {
23
+		border = style.getBorder("border", DEmptyBorder.ELEMENT);
24
+		backgroundColor = style.getColor("backgroundColor", 0);
25
+		margin = style.getMargin("margin", DMargin.EMPTY_ELEMENT);
26
+		shape = style.getShape("shape", DRectangleShape.ELEMENT);
27
+		shadow = style.getShadow("shadow", DShadow.NONE_ELEMENT);
28
+	}
29
+}

+ 5
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DEmptyStyleDefinition.java View File

@@ -54,4 +54,9 @@ public class DEmptyStyleDefinition implements DStyleDefinition {
54 54
 	public DMargin getMargin(String name, DMarginElement defaultValue) {
55 55
 		return defaultValue.eval(context);
56 56
 	}
57
+	
58
+	@Override
59
+	public DShape getShape(String name, DShapeElement defaultValue) {
60
+		return defaultValue.eval(context);
61
+	}
57 62
 }

+ 10
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DMargin.java View File

@@ -5,6 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.style;
7 7
 
8
+import org.openzen.drawablegui.DIRectangle;
9
+
8 10
 /**
9 11
  *
10 12
  * @author Hoofdgebruiker
@@ -36,4 +38,12 @@ public class DMargin {
36 38
 	public int getHorizontal() {
37 39
 		return left + right;
38 40
 	}
41
+	
42
+	public DIRectangle apply(DIRectangle bounds) {
43
+		return new DIRectangle(
44
+				bounds.x + left,
45
+				bounds.y + top,
46
+				bounds.width - left - right,
47
+				bounds.height - top - bottom);
48
+	}
39 49
 }

+ 23
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DRectangleShape.java View File

@@ -0,0 +1,23 @@
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.style;
7
+
8
+import org.openzen.drawablegui.DIRectangle;
9
+import org.openzen.drawablegui.DPath;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class DRectangleShape implements DShape {
16
+	public static final DRectangleShape INSTANCE = new DRectangleShape();
17
+	public static final DShapeElement ELEMENT = context -> INSTANCE;
18
+
19
+	@Override
20
+	public DPath instance(DIRectangle bounds) {
21
+		return DPath.rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
22
+	}
23
+}

+ 36
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DRoundedRectangleShape.java View File

@@ -0,0 +1,36 @@
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.style;
7
+
8
+import org.openzen.drawablegui.DIRectangle;
9
+import org.openzen.drawablegui.DPath;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class DRoundedRectangleShape implements DShape {
16
+	private final float radiusTopLeft;
17
+	private final float radiusTopRight;
18
+	private final float radiusBottomLeft;
19
+	private final float radiusBottomRight;
20
+	
21
+	public DRoundedRectangleShape(float radius) {
22
+		this(radius, radius, radius, radius);
23
+	}
24
+	
25
+	public DRoundedRectangleShape(float radiusTopLeft, float radiusTopRight, float radiusBottomLeft, float radiusBottomRight) {
26
+		this.radiusTopLeft = radiusTopLeft;
27
+		this.radiusTopRight = radiusTopRight;
28
+		this.radiusBottomLeft = radiusBottomLeft;
29
+		this.radiusBottomRight = radiusBottomRight;
30
+	}
31
+
32
+	@Override
33
+	public DPath instance(DIRectangle bounds) {
34
+		return DPath.roundedRectangle(bounds.x, bounds.y, bounds.width, bounds.height, radiusTopLeft, radiusTopRight, radiusBottomLeft, radiusBottomRight);
35
+	}
36
+}

+ 17
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DShape.java View File

@@ -0,0 +1,17 @@
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.style;
7
+
8
+import org.openzen.drawablegui.DIRectangle;
9
+import org.openzen.drawablegui.DPath;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public interface DShape {
16
+	DPath instance(DIRectangle bounds);
17
+}

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

@@ -0,0 +1,22 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.drawablegui.style;
7
+
8
+import org.openzen.drawablegui.DUIContext;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+@FunctionalInterface
15
+public interface DShapeElement extends DStyleElement {
16
+	DShape eval(DUIContext context);
17
+	
18
+	@Override
19
+	default DShapeElement asShape() {
20
+		return this;
21
+	}
22
+}

+ 8
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DSimpleStylesheet.java View File

@@ -88,5 +88,13 @@ public class DSimpleStylesheet implements DStylesheet {
88 88
 			
89 89
 			return elements.get(name).asMargin().eval(context);
90 90
 		}
91
+		
92
+		@Override
93
+		public DShape getShape(String name, DShapeElement defaultValue) {
94
+			if (!elements.containsKey(name))
95
+				return defaultValue.eval(context);
96
+			
97
+			return elements.get(name).asShape().eval(context);
98
+		}
91 99
 	}
92 100
 }

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

@@ -21,6 +21,10 @@ public class DStyleClass {
21 21
 		return new DStyleClass(null, NO_CLASSES, stylesheet);
22 22
 	}
23 23
 	
24
+	public static DStyleClass inline(String id, DStylesheet stylesheet) {
25
+		return new DStyleClass(id, NO_CLASSES, stylesheet);
26
+	}
27
+	
24 28
 	public final String id;
25 29
 	public final String[] classes;
26 30
 	public final DStylesheet inline;

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

@@ -26,4 +26,6 @@ public interface DStyleDefinition {
26 26
 	public DBorder getBorder(String name, DBorderElement defaultValue);
27 27
 	
28 28
 	public DMargin getMargin(String name, DMarginElement defaultValue);
29
+	
30
+	public DShape getShape(String name, DShapeElement defaultValue);
29 31
 }

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

@@ -38,4 +38,8 @@ public interface DStyleElement {
38 38
 	default DShadowElement asShadow() {
39 39
 		throw new RuntimeException("Not a shadow!");
40 40
 	}
41
+	
42
+	default DShapeElement asShape() {
43
+		throw new RuntimeException("Not a shape!");
44
+	}
41 45
 }

+ 5
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/style/DStylesheetBuilder.java View File

@@ -55,6 +55,11 @@ public class DStylesheetBuilder {
55 55
 		return this;
56 56
 	}
57 57
 	
58
+	public DStylesheetBuilder shape(String name, DShapeElement shape) {
59
+		elements.put(name, shape);
60
+		return this;
61
+	}
62
+	
58 63
 	public DStylesheet build() {
59 64
 		return new DSimpleStylesheet(elements);
60 65
 	}

+ 3
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingRoot.java View File

@@ -79,10 +79,13 @@ public final class SwingRoot extends Component implements ComponentListener, Mou
79 79
 			component.setBounds(new DIRectangle(0, 0, getWidth(), getHeight()));
80 80
 		}
81 81
 		
82
+		long start = System.currentTimeMillis();
82 83
 		Rectangle clipBounds = g.getClipBounds();
83 84
 		DIRectangle clipBounds2 = clipBounds == null ? null : new DIRectangle(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
84 85
 		SwingCanvas canvas = new SwingCanvas((Graphics2D) g, context, clipBounds2);
85 86
 		component.paint(canvas);
87
+		
88
+		System.out.println("Paint in " + (System.currentTimeMillis() - start) + " ms");
86 89
 	}
87 90
 
88 91
 	@Override

+ 1
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingWindow.java View File

@@ -168,6 +168,7 @@ public final class SwingWindow extends JFrame implements WindowListener, WindowS
168 168
 	@Override
169 169
 	public void windowStateChanged(WindowEvent e) {
170 170
 		state.setValue(getStateFromWindowState());
171
+		swingComponent.repaint();
171 172
 	}
172 173
 	
173 174
 	private void updateBounds() {

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/tree/DTreeViewStyle.java View File

@@ -37,7 +37,7 @@ public class DTreeViewStyle {
37 37
 	private DTreeViewStyle() {
38 38
 		nodeOpenedIcon = ExpandedArrow.INSTANCE;
39 39
 		nodeClosedIcon = CollapsedArrow.INSTANCE;
40
-		backgroundColor = 0xFFFFFFFF;
40
+		backgroundColor = 0;
41 41
 		borderColor = 0xFF888888;
42 42
 		padding = new DDpDimension(3);
43 43
 		rowSpacing = new DDpDimension(2);

+ 15
- 10
IDE/src/main/java/org/openzen/zenscript/ide/ui/dialog/CreatePackageDialog.java View File

@@ -8,14 +8,17 @@ package org.openzen.zenscript.ide.ui.dialog;
8 8
 import org.openzen.drawablegui.DAnchor;
9 9
 import org.openzen.drawablegui.DButton;
10 10
 import org.openzen.drawablegui.DComponent;
11
-import org.openzen.drawablegui.layout.DHorizontalLayout;
12 11
 import org.openzen.drawablegui.DIRectangle;
13 12
 import org.openzen.drawablegui.DInputField;
14 13
 import org.openzen.drawablegui.DLabel;
15 14
 import org.openzen.drawablegui.DUIWindow;
16
-import org.openzen.drawablegui.layout.DVerticalLayout;
17 15
 import org.openzen.drawablegui.form.DForm;
18 16
 import org.openzen.drawablegui.form.DFormComponent;
17
+import org.openzen.drawablegui.layout.DLinearLayout;
18
+import org.openzen.drawablegui.layout.DLinearLayout.Alignment;
19
+import org.openzen.drawablegui.layout.DLinearLayout.Element;
20
+import org.openzen.drawablegui.layout.DLinearLayout.ElementAlignment;
21
+import org.openzen.drawablegui.layout.DLinearLayout.Orientation;
19 22
 import org.openzen.drawablegui.live.ImmutableLiveBool;
20 23
 import org.openzen.drawablegui.live.ImmutableLiveString;
21 24
 import org.openzen.drawablegui.live.SimpleLiveString;
@@ -56,17 +59,19 @@ public class CreatePackageDialog {
56 59
 
57 60
 		DButton ok = new DButton(DStyleClass.EMPTY, new SimpleLiveString("Create"), ImmutableLiveBool.FALSE, this::ok);
58 61
 		DButton cancel = new DButton(DStyleClass.EMPTY, new SimpleLiveString("Cancel"), ImmutableLiveBool.FALSE, this::cancel);
59
-		DHorizontalLayout buttons = new DHorizontalLayout(
62
+		DLinearLayout buttons = new DLinearLayout(
60 63
 				DStyleClass.EMPTY,
61
-				DHorizontalLayout.Alignment.RIGHT,
62
-				new DHorizontalLayout.Element(cancel, 0, 0, DHorizontalLayout.ElementAlignment.TOP),
63
-				new DHorizontalLayout.Element(ok, 0, 0, DHorizontalLayout.ElementAlignment.TOP));
64
+				Orientation.HORIZONTAL,
65
+				Alignment.RIGHT,
66
+				new Element(cancel, 0, 0, ElementAlignment.TOP),
67
+				new Element(ok, 0, 0, ElementAlignment.TOP));
64 68
 
65
-		root = new DVerticalLayout(
69
+		root = new DLinearLayout(
66 70
 				DStyleClass.EMPTY,
67
-				DVerticalLayout.Alignment.MIDDLE,
68
-				new DVerticalLayout.Element(form, 1, 1, DVerticalLayout.ElementAlignment.CENTER),
69
-				new DVerticalLayout.Element(buttons, 0, 0, DVerticalLayout.ElementAlignment.RIGHT));
71
+				Orientation.VERTICAL,
72
+				Alignment.MIDDLE,
73
+				new Element(form, 1, 1, ElementAlignment.CENTER),
74
+				new Element(buttons, 0, 0, ElementAlignment.RIGHT));
70 75
 	}
71 76
 	
72 77
 	public void open(DUIWindow parent) {

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

@@ -8,14 +8,17 @@ package org.openzen.zenscript.ide.ui.dialog;
8 8
 import org.openzen.drawablegui.DAnchor;
9 9
 import org.openzen.drawablegui.DButton;
10 10
 import org.openzen.drawablegui.DComponent;
11
-import org.openzen.drawablegui.layout.DHorizontalLayout;
12 11
 import org.openzen.drawablegui.DIRectangle;
13 12
 import org.openzen.drawablegui.DInputField;
14 13
 import org.openzen.drawablegui.DLabel;
15 14
 import org.openzen.drawablegui.DUIWindow;
16
-import org.openzen.drawablegui.layout.DVerticalLayout;
17 15
 import org.openzen.drawablegui.form.DForm;
18 16
 import org.openzen.drawablegui.form.DFormComponent;
17
+import org.openzen.drawablegui.layout.DLinearLayout;
18
+import org.openzen.drawablegui.layout.DLinearLayout.Alignment;
19
+import org.openzen.drawablegui.layout.DLinearLayout.Element;
20
+import org.openzen.drawablegui.layout.DLinearLayout.ElementAlignment;
21
+import org.openzen.drawablegui.layout.DLinearLayout.Orientation;
19 22
 import org.openzen.drawablegui.live.ImmutableLiveBool;
20 23
 import org.openzen.drawablegui.live.ImmutableLiveString;
21 24
 import org.openzen.drawablegui.live.SimpleLiveString;
@@ -60,17 +63,19 @@ public class CreateSourceFileDialog {
60 63
 
61 64
 		DButton ok = new DButton(DStyleClass.EMPTY, new SimpleLiveString("Create"), ImmutableLiveBool.FALSE, this::ok);
62 65
 		DButton cancel = new DButton(DStyleClass.EMPTY, new SimpleLiveString("Cancel"), ImmutableLiveBool.FALSE, this::cancel);
63
-		DHorizontalLayout buttons = new DHorizontalLayout(
66
+		DLinearLayout buttons = new DLinearLayout(
64 67
 				DStyleClass.EMPTY,
65
-				DHorizontalLayout.Alignment.RIGHT,
66
-				new DHorizontalLayout.Element(cancel, 0, 0, DHorizontalLayout.ElementAlignment.TOP),
67
-				new DHorizontalLayout.Element(ok, 0, 0, DHorizontalLayout.ElementAlignment.TOP));
68
+				Orientation.HORIZONTAL,
69
+				Alignment.RIGHT,
70
+				new Element(cancel, 0, 0, ElementAlignment.TOP),
71
+				new Element(ok, 0, 0, ElementAlignment.TOP));
68 72
 
69
-		root = new DVerticalLayout(
73
+		root = new DLinearLayout(
70 74
 				DStyleClass.EMPTY,
71
-				DVerticalLayout.Alignment.MIDDLE,
72
-				new DVerticalLayout.Element(form, 1, 1, DVerticalLayout.ElementAlignment.CENTER),
73
-				new DVerticalLayout.Element(buttons, 0, 0, DVerticalLayout.ElementAlignment.RIGHT));
75
+				Orientation.VERTICAL,
76
+				Alignment.MIDDLE,
77
+				new Element(form, 1, 1, ElementAlignment.CENTER),
78
+				new Element(buttons, 0, 0, ElementAlignment.RIGHT));
74 79
 	}
75 80
 	
76 81
 	public void open(DUIWindow parent) {

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

@@ -8,6 +8,7 @@ package org.openzen.zenscript.ide.ui.view;
8 8
 import org.openzen.drawablegui.DFont;
9 9
 import org.openzen.drawablegui.DFontFamily;
10 10
 import org.openzen.drawablegui.style.DDpDimension;
11
+import org.openzen.drawablegui.style.DShadow;
11 12
 import org.openzen.drawablegui.style.DStyleDefinition;
12 13
 
13 14
 /**
@@ -22,6 +23,7 @@ public class StatusBarStyle {
22 23
 	public final DFont font;
23 24
 	public final int backgroundColor;
24 25
 	public final int textColor;
26
+	public final DShadow shadow;
25 27
 	
26 28
 	public StatusBarStyle(DStyleDefinition style) {
27 29
 		paddingTop = style.getDimension("paddingTop", new DDpDimension(4));
@@ -32,5 +34,6 @@ public class StatusBarStyle {
32 34
 		font = style.getFont("font", context -> new DFont(DFontFamily.UI, false, false, false, (int)(14 * context.getScale())));
33 35
 		backgroundColor = style.getColor("backgroundColor", 0xFFF0F0F0);
34 36
 		textColor = style.getColor("textColor", 0xFF000000);
37
+		shadow = style.getShadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()));
35 38
 	}
36 39
 }

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

@@ -10,6 +10,8 @@ import org.openzen.drawablegui.DComponent;
10 10
 import org.openzen.drawablegui.DSizing;
11 11
 import org.openzen.drawablegui.DFontMetrics;
12 12
 import org.openzen.drawablegui.DIRectangle;
13
+import org.openzen.drawablegui.DPath;
14
+import org.openzen.drawablegui.DTransform2D;
13 15
 import org.openzen.drawablegui.live.LiveObject;
14 16
 import org.openzen.drawablegui.live.SimpleLiveObject;
15 17
 import org.openzen.drawablegui.DUIContext;
@@ -69,7 +71,7 @@ public class StatusBarView implements DComponent {
69 71
 
70 72
 	@Override
71 73
 	public void paint(DCanvas canvas) {
72
-		canvas.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height, style.backgroundColor);
74
+		canvas.shadowPath(DPath.rectangle(bounds.x, bounds.y, bounds.width, bounds.height), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
73 75
 		canvas.drawText(style.font, style.textColor, style.paddingLeft, style.paddingTop + fontMetrics.getAscent(), content.getValue());
74 76
 	}
75 77
 

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

@@ -82,7 +82,7 @@ public class TabbedView extends BaseComponentGroup {
82 82
 		path = parent.getChild("tabbedView", styleClass);
83 83
 		style = new TabbedViewStyle(context.getStylesheets().get(context, path));
84 84
 		fontMetrics = context.getFontMetrics(style.tabFont);
85
-		totalTabHeight = style.paddingTop + style.paddingBottom + fontMetrics.getAscent() + fontMetrics.getDescent();
85
+		totalTabHeight = style.tabBorder.getPaddingVertical() + fontMetrics.getAscent() + fontMetrics.getDescent();
86 86
 		
87 87
 		for (TabbedViewComponent tab : tabs)
88 88
 			prepare(tab);
@@ -128,13 +128,12 @@ public class TabbedView extends BaseComponentGroup {
128 128
 
129 129
 	@Override
130 130
 	public void close() {
131
-		
131
+		for (Map.Entry<TabbedViewTab, ListenerHandle<LiveObject.Listener<DSizing>>> entry : tabSizeListeners.entrySet()) {
132
+			entry.getValue().close();
133
+		}
132 134
 	}
133 135
 	
134 136
 	private void repaintTabs() {
135
-		if (context == null)
136
-			return;
137
-		
138 137
 		context.repaint(bounds.x, bounds.y, bounds.width, totalTabHeight);
139 138
 	}
140 139
 	
@@ -187,11 +186,11 @@ public class TabbedView extends BaseComponentGroup {
187 186
 	private class TabListListener implements LiveList.Listener<TabbedViewComponent> {
188 187
 		@Override
189 188
 		public void onInserted(int index, TabbedViewComponent value) {
190
-			if (currentTab.getValue() == null)
191
-				currentTab.setValue(value);
192
-			
193 189
 			prepare(value);
194 190
 			layoutTabs();
191
+			
192
+			if (currentTab.getValue() == null)
193
+				currentTab.setValue(value);
195 194
 		}
196 195
 
197 196
 		@Override

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

@@ -7,44 +7,36 @@ package org.openzen.zenscript.ide.ui.view;
7 7
 
8 8
 import org.openzen.drawablegui.DFont;
9 9
 import org.openzen.drawablegui.DFontFamily;
10
+import org.openzen.drawablegui.border.DBorder;
11
+import org.openzen.drawablegui.border.DCompositeBorder;
12
+import org.openzen.drawablegui.border.DLineBorder;
13
+import org.openzen.drawablegui.border.DPaddedBorder;
14
+import org.openzen.drawablegui.style.DBaseStyle;
10 15
 import org.openzen.drawablegui.style.DDpDimension;
11
-import org.openzen.drawablegui.style.DPxDimension;
12 16
 import org.openzen.drawablegui.style.DStyleDefinition;
13 17
 
14 18
 /**
15 19
  *
16 20
  * @author Hoofdgebruiker
17 21
  */
18
-public class TabbedViewStyle {
19
-	public final int backgroundColor;
22
+public class TabbedViewStyle extends DBaseStyle {
20 23
 	public final DFont tabFont;
21 24
 	public final int tabFontColor;
25
+	public final DBorder tabBorder;
22 26
 	
23
-	public final int paddingTop;
24
-	public final int paddingBottom;
25
-	public final int paddingLeft;
26
-	public final int paddingRight;
27 27
 	public final int tabBarSpacingLeft;
28 28
 	public final int tabBarSpacingRight;
29 29
 	public final int tabSpacing;
30 30
 	
31
-	public final int borderColor;
32
-	public final int borderWidth;
33
-	
34 31
 	public TabbedViewStyle(DStyleDefinition style) {
35
-		backgroundColor = style.getColor("backgroundColor", 0xFFEEEEEE);
32
+		super(style);
33
+		
36 34
 		tabFont = style.getFont("tabFont", context -> new DFont(DFontFamily.UI, false, false, false, (int)(12 * context.getScale())));
37 35
 		tabFontColor = style.getColor("tabFontColor", 0xFF000000);
36
+		tabBorder = style.getBorder("tabBorder", context -> new DCompositeBorder(new DLineBorder(0xFF888888, 1), new DPaddedBorder(context.dp(4))));
38 37
 		
39
-		paddingTop = style.getDimension("paddingTop", new DDpDimension(4));
40
-		paddingBottom = style.getDimension("paddingTop", new DDpDimension(4));
41
-		paddingLeft = style.getDimension("paddingLeft", new DDpDimension(4));
42
-		paddingRight = style.getDimension("paddingRight", new DDpDimension(4));
43 38
 		tabBarSpacingLeft = style.getDimension("tabBarSpacingLeft", new DDpDimension(4));
44 39
 		tabBarSpacingRight = style.getDimension("tabBarSpacingRight", new DDpDimension(4));
45 40
 		tabSpacing = style.getDimension("tabSpacing", new DDpDimension(4));
46
-		
47
-		borderColor = style.getColor("borderColor", 0xFF888888);
48
-		borderWidth = style.getDimension("borderWidth", new DPxDimension(1));
49 41
 	}
50 42
 }

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

@@ -9,6 +9,7 @@ import org.openzen.drawablegui.DEmptyView;
9 9
 import org.openzen.drawablegui.scroll.DScrollPane;
10 10
 import org.openzen.drawablegui.layout.DSideLayout;
11 11
 import org.openzen.drawablegui.live.LiveString;
12
+import org.openzen.drawablegui.live.SimpleLiveInt;
12 13
 import org.openzen.drawablegui.live.SimpleLiveString;
13 14
 import org.openzen.drawablegui.style.DStyleClass;
14 15
 import org.openzen.drawablegui.style.DStylesheetBuilder;
@@ -38,7 +39,9 @@ public final class WindowView extends DSideLayout {
38 39
 		
39 40
 		projectBrowser = new ProjectBrowser(window, host);
40 41
 		
41
-		setMain(tabs = new TabbedView(DStyleClass.EMPTY));
42
+		setMain(tabs = new TabbedView(DStyleClass.inline(new DStylesheetBuilder()
43
+				.marginDp("margin", 3)
44
+				.build())));
42 45
 		add(Side.LEFT, projectBrowser.view);
43 46
 		add(Side.BOTTOM, new StatusBarView(DStyleClass.EMPTY, status));
44 47
 		add(Side.TOP, new AspectBarView(DStyleClass.EMPTY, window.aspectBar));
@@ -53,7 +56,7 @@ public final class WindowView extends DSideLayout {
53 56
 			TabbedViewComponent tab = new TabbedViewComponent(
54 57
 					sourceFile.getName(),
55 58
 					null,
56
-					new DScrollPane(DStyleClass.EMPTY, editor),
59
+					new DScrollPane(DStyleClass.EMPTY, editor, new SimpleLiveInt(0)),
57 60
 					editor.isUpdated());
58 61
 			tabs.tabs.add(tab);
59 62
 			tabs.currentTab.setValue(tab);

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

@@ -5,16 +5,78 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.ui.view.output;
7 7
 
8
+import org.openzen.drawablegui.DCanvas;
9
+import org.openzen.drawablegui.DComponent;
10
+import org.openzen.drawablegui.DIRectangle;
11
+import org.openzen.drawablegui.DPath;
12
+import org.openzen.drawablegui.DSizing;
13
+import org.openzen.drawablegui.DTransform2D;
14
+import org.openzen.drawablegui.DUIContext;
8 15
 import org.openzen.drawablegui.live.LiveList;
16
+import org.openzen.drawablegui.live.LiveObject;
17
+import org.openzen.drawablegui.live.MutableLiveObject;
18
+import org.openzen.drawablegui.style.DStyleClass;
19
+import org.openzen.drawablegui.style.DStylePath;
9 20
 
10 21
 /**
11 22
  *
12 23
  * @author Hoofdgebruiker
13 24
  */
14
-public class OutputView {
15
-	public final LiveList<OutputLine> lines;
25
+public class OutputView implements DComponent {
26
+	private final MutableLiveObject<DSizing> sizing = DSizing.create();
27
+	private final DStyleClass styleClass;
28
+	private final LiveList<OutputLine> lines;
16 29
 	
17
-	public OutputView(LiveList<OutputLine> lines) {
30
+	private DUIContext context;
31
+	private DIRectangle bounds;
32
+	private DPath shape;
33
+	private OutputViewStyle style;
34
+	
35
+	public OutputView(DStyleClass styleClass, LiveList<OutputLine> lines) {
36
+		this.styleClass = styleClass;
18 37
 		this.lines = lines;
19 38
 	}
39
+
40
+	@Override
41
+	public void setContext(DStylePath parent, DUIContext context) {
42
+		this.context = context;
43
+		
44
+		DStylePath path = parent.getChild("outputview", styleClass);
45
+		style = new OutputViewStyle(context.getStylesheets().get(context, path));
46
+	}
47
+
48
+	@Override
49
+	public MutableLiveObject<DSizing> getSizing() {
50
+		return sizing;
51
+	}
52
+
53
+	@Override
54
+	public DIRectangle getBounds() {
55
+		return bounds;
56
+	}
57
+
58
+	@Override
59
+	public int getBaselineY() {
60
+		return -1;
61
+	}
62
+
63
+	@Override
64
+	public void setBounds(DIRectangle bounds) {
65
+		this.bounds = bounds;
66
+		shape = style.shape.instance(bounds);
67
+	}
68
+
69
+	@Override
70
+	public void paint(DCanvas canvas) {
71
+		canvas.shadowPath(
72
+				shape,
73
+				DTransform2D.IDENTITY,
74
+				style.backgroundColor,
75
+				style.shadow);
76
+	}
77
+
78
+	@Override
79
+	public void close() {
80
+		
81
+	}
20 82
 }

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

@@ -0,0 +1,35 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.view.output;
7
+
8
+import org.openzen.drawablegui.DFont;
9
+import org.openzen.drawablegui.DFontFamily;
10
+import org.openzen.drawablegui.border.DBorder;
11
+import org.openzen.drawablegui.border.DPaddedBorder;
12
+import org.openzen.drawablegui.style.DRoundedRectangleShape;
13
+import org.openzen.drawablegui.style.DShadow;
14
+import org.openzen.drawablegui.style.DShape;
15
+import org.openzen.drawablegui.style.DStyleDefinition;
16
+
17
+/**
18
+ *
19
+ * @author Hoofdgebruiker
20
+ */
21
+public class OutputViewStyle {
22
+	public final int backgroundColor;
23
+	public final DBorder border;
24
+	public final DShadow shadow;
25
+	public final DShape shape;
26
+	public final DFont font;
27
+	
28
+	public OutputViewStyle(DStyleDefinition style) {
29
+		backgroundColor = style.getColor("backgroundColor", 0xFFFFFFFF);
30
+		border = style.getBorder("border", context -> new DPaddedBorder(context.dp(8)));
31
+		shadow = style.getShadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()));
32
+		shape = style.getShape("shape", context -> new DRoundedRectangleShape(context.dp(2)));
33
+		font = style.getFont("font", context -> new DFont(DFontFamily.CODE, false, false, false, context.sp(14)));
34
+	}
35
+}

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

@@ -6,17 +6,22 @@
6 6
 package org.openzen.zenscript.ide.ui.view.project;
7 7
 
8 8
 import org.openzen.drawablegui.DComponent;
9
-import org.openzen.drawablegui.layout.DHorizontalLayout;
10 9
 import org.openzen.drawablegui.DSizing;
11
-import org.openzen.drawablegui.layout.DVerticalLayout;
12 10
 import org.openzen.drawablegui.border.DEmptyBorder;
13 11
 import org.openzen.drawablegui.border.DPaddedBorder;
12
+import org.openzen.drawablegui.layout.DLinearLayout;
13
+import org.openzen.drawablegui.layout.DLinearLayout.Alignment;
14
+import org.openzen.drawablegui.layout.DLinearLayout.Element;
15
+import org.openzen.drawablegui.layout.DLinearLayout.ElementAlignment;
16
+import org.openzen.drawablegui.layout.DLinearLayout.Orientation;
14 17
 import org.openzen.drawablegui.live.ImmutableLiveString;
15 18
 import org.openzen.drawablegui.live.LiveBool;
16 19
 import org.openzen.drawablegui.live.LivePredicateBool;
17 20
 import org.openzen.drawablegui.live.MutableLiveObject;
21
+import org.openzen.drawablegui.live.SimpleLiveInt;
18 22
 import org.openzen.drawablegui.live.SimpleLiveObject;
19 23
 import org.openzen.drawablegui.scroll.DScrollPane;
24
+import org.openzen.drawablegui.style.DRoundedRectangleShape;
20 25
 import org.openzen.drawablegui.style.DShadow;
21 26
 import org.openzen.drawablegui.style.DStyleClass;
22 27
 import org.openzen.drawablegui.style.DStylesheetBuilder;
@@ -74,31 +79,41 @@ public class ProjectBrowser {
74 79
 					dialog.open(e.window);
75 80
 				});
76 81
 		
77
-		DHorizontalLayout toolbar = new DHorizontalLayout(
82
+		DLinearLayout toolbar = new DLinearLayout(
78 83
 				DStyleClass.inline(new DStylesheetBuilder()
79 84
 						.border("border", context -> new DPaddedBorder(0, context.dp(2), 0, 0))
85
+						.shape("shape", context -> new DRoundedRectangleShape(context.dp(2), context.dp(2), 0, 0))
86
+						.color("backgroundColor", 0xFFFFFFFF)
87
+						.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
80 88
 						.dimensionPx("spacing", 0)
81 89
 						.build()),
82
-				DHorizontalLayout.Alignment.LEFT,
83
-				new DHorizontalLayout.Element(addPackageButton, 0, 0, DHorizontalLayout.ElementAlignment.TOP),
84
-				new DHorizontalLayout.Element(addFileButton, 0, 0, DHorizontalLayout.ElementAlignment.TOP));
90
+				Orientation.HORIZONTAL,
91
+				Alignment.LEFT,
92
+				new Element(addPackageButton, 0, 0, ElementAlignment.TOP),
93
+				new Element(addFileButton, 0, 0, ElementAlignment.TOP));
85 94
 		DTreeView projectTree = new DTreeView(
86 95
 				DTreeViewStyle.DEFAULT,
87 96
 				new RootTreeNode(this, host), false);
88 97
 		projectTree.getSizing().setValue(new DSizing(500, 500));
98
+		DScrollPane treeScrollPane = new DScrollPane(
99
+				DStyleClass.inline("projectView", new DStylesheetBuilder()
100
+						.shape("shape", context -> new DRoundedRectangleShape(0, 0, context.dp(2), context.dp(2)))
101
+						.color("backgroundColor", 0xFFFFFFFF)
102
+						.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
103
+						.build()),
104
+				projectTree,
105
+				new SimpleLiveInt(0));
89 106
 		
90
-		view = new DVerticalLayout(
107
+		view = new DLinearLayout(
91 108
 				DStyleClass.inline(new DStylesheetBuilder()
92 109
 						.border("border", DEmptyBorder.ELEMENT)
93
-						.dimensionPx("spacing", 0)
110
+						.dimensionDp("spacing", 2)
94 111
 						.marginDp("margin", 3)
95
-						.dimensionDp("cornerRadius", 2)
96
-						.color("backgroundColor", 0xFFFFFFFF)
97
-						.shadow("shadow", context -> new DShadow(0xFF888888, 0, 0.5f * context.getScale(), 3 * context.getScale()))
98 112
 						.build()),
99
-				DVerticalLayout.Alignment.TOP,
100
-				new DVerticalLayout.Element(toolbar, 0, 0, DVerticalLayout.ElementAlignment.STRETCH),
101
-				new DVerticalLayout.Element(new DScrollPane(DStyleClass.forId("projectView"), projectTree), 1, 1, DVerticalLayout.ElementAlignment.STRETCH));
113
+				Orientation.VERTICAL,
114
+				Alignment.TOP,
115
+				new Element(toolbar, 0, 0, ElementAlignment.STRETCH),
116
+				new Element(treeScrollPane, 1, 1, ElementAlignment.STRETCH));
102 117
 	}
103 118
 	
104 119
 	public void setContextModule(IDEModule module) {

Loading…
Cancel
Save