Bläddra i källkod

Added tabs + support for multiple open source files

Stan Hebben 6 år sedan
förälder
incheckning
637b2399d5
46 ändrade filer med 1115 tillägg och 150 borttagningar
  1. 0
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/DCanvas.java
  2. 4
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/DComponent.java
  3. 0
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/DEmptyView.java
  4. 3
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/DIRectangle.java
  5. 0
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/DPathBoundsCalculator.java
  6. 6
    4
      DrawableGui/src/main/java/org/openzen/drawablegui/DSideLayout.java
  7. 16
    0
      DrawableGui/src/main/java/org/openzen/drawablegui/DTransform2D.java
  8. 0
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/DUIContext.java
  9. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DBorder.java
  10. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DCustomWindowBorder.java
  11. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DEmptyBorder.java
  12. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/border/DLineBorder.java
  13. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollBar.java
  14. 11
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java
  15. 2
    2
      DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingCanvas.java
  16. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingRoot.java
  17. 1
    1
      DrawableGui/src/main/java/org/openzen/drawablegui/tree/DTreeView.java
  18. 2
    2
      DrawableGuiIconConverter/src/main/java/org/openzen/drawablegui/iconconverter/Main.java
  19. 4
    61
      IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEAspectBar.java
  20. 15
    3
      IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEDockWindow.java
  21. 12
    5
      IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEWindow.java
  22. 5
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/AddBoxIcon.java
  23. 52
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/BuildIcon.java
  24. 42
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/PlayIcon.java
  25. 2
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/SettingsIcon.java
  26. 53
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/ShadedCodeIcon.java
  27. 61
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/ShadedProjectIcon.java
  28. 61
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/ShadedSaveIcon.java
  29. 1
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/IconButtonControl.java
  30. 1
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/StatusBarView.java
  31. 197
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedView.java
  32. 25
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewComponent.java
  33. 60
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewStyle.java
  34. 153
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTab.java
  35. 102
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabClose.java
  36. 21
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabCloseStyle.java
  37. 58
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabStyle.java
  38. 23
    7
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/WindowView.java
  39. 4
    4
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarSelectorButton.java
  40. 41
    27
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarView.java
  41. 1
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/WindowActionButton.java
  42. 34
    10
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java
  43. 26
    3
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenLine.java
  44. 1
    2
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenModel.java
  45. 8
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/project/ProjectTreeNode.java
  46. 1
    1
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java

+ 0
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/DCanvas.java Visa fil

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.listeners.DIRectangle;
9 8
 import org.openzen.drawablegui.style.DShadow;
10 9
 
11 10
 /**

+ 4
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/DComponent.java Visa fil

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.listeners.DIRectangle;
9 8
 import java.io.Closeable;
10 9
 import org.openzen.drawablegui.live.LiveObject;
11 10
 import org.openzen.drawablegui.style.DStylePath;
@@ -25,6 +24,10 @@ public interface DComponent extends Closeable {
25 24
 	
26 25
 	void paint(DCanvas canvas);
27 26
 	
27
+	default void onMounted() {}
28
+	
29
+	default void onUnmounted() {}
30
+	
28 31
 	default void onMouseEnter(DMouseEvent e) {}
29 32
 	
30 33
 	default void onMouseExit(DMouseEvent e) {}

+ 0
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/DEmptyView.java Visa fil

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.listeners.DIRectangle;
9 8
 import org.openzen.drawablegui.live.ImmutableLiveObject;
10 9
 import org.openzen.drawablegui.live.LiveObject;
11 10
 import org.openzen.drawablegui.style.DStylePath;

DrawableGui/src/main/java/org/openzen/drawablegui/listeners/DIRectangle.java → DrawableGui/src/main/java/org/openzen/drawablegui/DIRectangle.java Visa fil

@@ -3,13 +3,15 @@
3 3
  * To change this template file, choose Tools | Templates
4 4
  * and open the template in the editor.
5 5
  */
6
-package org.openzen.drawablegui.listeners;
6
+package org.openzen.drawablegui;
7 7
 
8 8
 /**
9 9
  *
10 10
  * @author Hoofdgebruiker
11 11
  */
12 12
 public class DIRectangle {
13
+	public static final DIRectangle EMPTY = new DIRectangle(0, 0, 0, 0);
14
+	
13 15
 	public final int x;
14 16
 	public final int y;
15 17
 	public final int width;

+ 0
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/DPathBoundsCalculator.java Visa fil

@@ -5,8 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.listeners.DIRectangle;
9
-
10 8
 /**
11 9
  *
12 10
  * @author Hoofdgebruiker

+ 6
- 4
DrawableGui/src/main/java/org/openzen/drawablegui/DSideLayout.java Visa fil

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.listeners.DIRectangle;
9 8
 import java.io.Closeable;
10 9
 import java.util.ArrayList;
11 10
 import java.util.List;
@@ -49,9 +48,12 @@ public class DSideLayout extends BaseComponentGroup {
49 48
 			this.main.close();
50 49
 		
51 50
 		this.main = component;
52
-		main.setContext(path, context);
53
-		setBounds(bounds);
54
-		context.repaint(bounds);
51
+		
52
+		if (context != null && bounds != null) {
53
+			main.setContext(path, context);
54
+			setBounds(bounds);
55
+			context.repaint(bounds);
56
+		}
55 57
 	}
56 58
 
57 59
 	@Override

+ 16
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/DTransform2D.java Visa fil

@@ -51,4 +51,20 @@ public final class DTransform2D {
51 51
 	public float getY(float x, float y) {
52 52
 		return x * yx + y * yy + dy;
53 53
 	}
54
+	
55
+	public DTransform2D mul(DTransform2D other) {
56
+		// [xx xy dx]   [xx xy dx]   [xx*xx+xy*yx xx*xy+xy*yy xx*dx+xy*dy+dx]
57
+		// [yx yy dy] x [yx yy dy] = [yx*xx+yy*yx yx*xy+yy*yy yx*dx+yy*dy+dy]
58
+		// [0  0  1 ]   [0  0  1 ]   [0           0           1             ]
59
+		DTransform2D a = this;
60
+		DTransform2D b = other;
61
+		return new DTransform2D(
62
+				a.xx * b.xx + a.xy * b.yx,
63
+				a.xx * b.xy + a.xy * b.yy,
64
+				a.yx * b.xx + a.yy * b.yx,
65
+				a.yx * b.xy + a.yx + b.xy,
66
+				a.xx * b.dx + a.xy * b.dy + dx,
67
+				a.yx * b.dx + a.yy * b.dy + dy
68
+		);
69
+	}
54 70
 }

+ 0
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/DUIContext.java Visa fil

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.drawablegui;
7 7
 
8
-import org.openzen.drawablegui.listeners.DIRectangle;
9 8
 import org.openzen.drawablegui.live.LiveObject;
10 9
 import org.openzen.drawablegui.style.DStyleSheets;
11 10
 

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/border/DBorder.java Visa fil

@@ -6,7 +6,7 @@
6 6
 package org.openzen.drawablegui.border;
7 7
 
8 8
 import org.openzen.drawablegui.DCanvas;
9
-import org.openzen.drawablegui.listeners.DIRectangle;
9
+import org.openzen.drawablegui.DIRectangle;
10 10
 
11 11
 /**
12 12
  *

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/border/DCustomWindowBorder.java Visa fil

@@ -13,7 +13,7 @@ import org.openzen.drawablegui.DPath;
13 13
 import org.openzen.drawablegui.DTransform2D;
14 14
 import org.openzen.drawablegui.DUIContext;
15 15
 import org.openzen.drawablegui.DUIWindow;
16
-import org.openzen.drawablegui.listeners.DIRectangle;
16
+import org.openzen.drawablegui.DIRectangle;
17 17
 import org.openzen.drawablegui.listeners.ListenerHandle;
18 18
 import org.openzen.drawablegui.live.ImmutableLiveObject;
19 19
 import org.openzen.drawablegui.live.LiveBool;

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/border/DEmptyBorder.java Visa fil

@@ -6,7 +6,7 @@
6 6
 package org.openzen.drawablegui.border;
7 7
 
8 8
 import org.openzen.drawablegui.DCanvas;
9
-import org.openzen.drawablegui.listeners.DIRectangle;
9
+import org.openzen.drawablegui.DIRectangle;
10 10
 import org.openzen.drawablegui.DUIContext;
11 11
 
12 12
 /**

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/border/DLineBorder.java Visa fil

@@ -7,7 +7,7 @@ package org.openzen.drawablegui.border;
7 7
 
8 8
 import org.openzen.drawablegui.DCanvas;
9 9
 import org.openzen.drawablegui.DTransform2D;
10
-import org.openzen.drawablegui.listeners.DIRectangle;
10
+import org.openzen.drawablegui.DIRectangle;
11 11
 import org.openzen.drawablegui.DUIContext;
12 12
 
13 13
 /**

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollBar.java Visa fil

@@ -9,7 +9,7 @@ import org.openzen.drawablegui.DCanvas;
9 9
 import org.openzen.drawablegui.DComponent;
10 10
 import org.openzen.drawablegui.DDimensionPreferences;
11 11
 import org.openzen.drawablegui.DMouseEvent;
12
-import org.openzen.drawablegui.listeners.DIRectangle;
12
+import org.openzen.drawablegui.DIRectangle;
13 13
 import org.openzen.drawablegui.listeners.ListenerHandle;
14 14
 import org.openzen.drawablegui.live.LiveInt;
15 15
 import org.openzen.drawablegui.live.LiveObject;

+ 11
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java Visa fil

@@ -11,7 +11,7 @@ import org.openzen.drawablegui.DComponent;
11 11
 import org.openzen.drawablegui.DDimensionPreferences;
12 12
 import org.openzen.drawablegui.DFont;
13 13
 import org.openzen.drawablegui.DFontMetrics;
14
-import org.openzen.drawablegui.listeners.DIRectangle;
14
+import org.openzen.drawablegui.DIRectangle;
15 15
 import org.openzen.drawablegui.DMouseEvent;
16 16
 import org.openzen.drawablegui.DTimerHandle;
17 17
 import org.openzen.drawablegui.listeners.ListenerHandle;
@@ -68,6 +68,16 @@ public class DScrollPane implements DComponent {
68 68
 			contentsHeight.setValue(newPreferences.preferredHeight);
69 69
 		});
70 70
 	}
71
+	
72
+	@Override
73
+	public void onMounted() {
74
+		contents.onMounted();
75
+	}
76
+	
77
+	@Override
78
+	public void onUnmounted() {
79
+		contents.onUnmounted();
80
+	}
71 81
 
72 82
 	@Override
73 83
 	public void setContext(DStylePath parent, DUIContext context) {

+ 2
- 2
DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingCanvas.java Visa fil

@@ -21,7 +21,7 @@ import org.openzen.drawablegui.DCanvas;
21 21
 import org.openzen.drawablegui.DFont;
22 22
 import org.openzen.drawablegui.DFontFamily;
23 23
 import org.openzen.drawablegui.DTransform2D;
24
-import org.openzen.drawablegui.listeners.DIRectangle;
24
+import org.openzen.drawablegui.DIRectangle;
25 25
 import org.openzen.drawablegui.DPath;
26 26
 import org.openzen.drawablegui.DPathBoundsCalculator;
27 27
 import org.openzen.drawablegui.DUIContext;
@@ -132,7 +132,7 @@ public class SwingCanvas implements DCanvas {
132 132
 		
133 133
 		GeneralPath jPath = context.getPath(path);
134 134
 		
135
-		BufferedImage image = new BufferedImage(bounds.width + 2 * offset, bounds.height + 2 * offset, BufferedImage.TYPE_INT_ARGB);
135
+		BufferedImage image = new BufferedImage(bounds.width + 2 * offset, bounds.height + 2 * offset, BufferedImage.TYPE_INT_ARGB_PRE);
136 136
 		Graphics2D imageG = (Graphics2D) image.getGraphics();
137 137
 		
138 138
 		imageG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/swing/SwingRoot.java Visa fil

@@ -20,7 +20,7 @@ import java.awt.event.MouseMotionListener;
20 20
 import java.awt.event.MouseWheelEvent;
21 21
 import java.awt.event.MouseWheelListener;
22 22
 import org.openzen.drawablegui.DComponent;
23
-import org.openzen.drawablegui.listeners.DIRectangle;
23
+import org.openzen.drawablegui.DIRectangle;
24 24
 import org.openzen.drawablegui.DKeyEvent;
25 25
 import static org.openzen.drawablegui.DKeyEvent.KeyCode.*;
26 26
 import org.openzen.drawablegui.DMouseEvent;

+ 1
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/tree/DTreeView.java Visa fil

@@ -15,7 +15,7 @@ import org.openzen.drawablegui.DDrawable;
15 15
 import org.openzen.drawablegui.DFontMetrics;
16 16
 import org.openzen.drawablegui.DMouseEvent;
17 17
 import org.openzen.drawablegui.DTransform2D;
18
-import org.openzen.drawablegui.listeners.DIRectangle;
18
+import org.openzen.drawablegui.DIRectangle;
19 19
 import org.openzen.drawablegui.listeners.ListenerHandle;
20 20
 import org.openzen.drawablegui.live.LiveBool;
21 21
 import org.openzen.drawablegui.live.LiveObject;

+ 2
- 2
DrawableGuiIconConverter/src/main/java/org/openzen/drawablegui/iconconverter/Main.java Visa fil

@@ -21,9 +21,9 @@ import org.w3c.dom.NodeList;
21 21
  */
22 22
 public class Main {
23 23
 	public static void main(String[] args) throws Exception {
24
-		String filename = "baseline-close-24px.svg"; //args[0];
24
+		String filename = "baseline-build-24px.svg"; //args[0];
25 25
 		//String filename = "baseline-dashboard-24px.svg";
26
-		String className = "ColorableCloseIcon";
26
+		String className = "BuildIcon";
27 27
 		File file = new File(filename);
28 28
 		if (!file.exists()) {
29 29
 			System.out.println("No such file: " + filename);

+ 4
- 61
IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEAspectBar.java Visa fil

@@ -5,73 +5,16 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.ui;
7 7
 
8
-import java.io.Closeable;
9
-import org.openzen.drawablegui.listeners.ListenerHandle;
10
-import org.openzen.drawablegui.listeners.ListenerList;
11 8
 import org.openzen.drawablegui.live.LiveArrayList;
12 9
 import org.openzen.drawablegui.live.LiveList;
10
+import org.openzen.drawablegui.live.LiveObject;
11
+import org.openzen.drawablegui.live.SimpleLiveObject;
13 12
 
14 13
 /**
15 14
  *
16 15
  * @author Hoofdgebruiker
17 16
  */
18 17
 public class IDEAspectBar {
19
-	public final LiveList<IDEAspectToolbar> aspectToolbars = new LiveArrayList<>(); // TODO: only expose read-only variant
20
-	private final ListenerList<Listener> listeners = new ListenerList<>();
21
-	
22
-	public ListenerHandle<Listener> addListener(Listener listener) {
23
-		return listeners.add(listener);
24
-	}
25
-	
26
-	public void addToolbar(IDEAspectToolbar toolbar) {
27
-		int index = insertToolbar(toolbar);
28
-		listeners.accept(listener -> listener.onAspectBarAdded(index, toolbar));
29
-	}
30
-	
31
-	public boolean removeToolbar(IDEAspectToolbar toolbar) {
32
-		int index = aspectToolbars.indexOf(toolbar);
33
-		if (index < 0)
34
-			return false;
35
-		
36
-		aspectToolbars.remove(index);
37
-		listeners.accept(listener -> listener.onAspectBarRemoved(index, toolbar));
38
-		return true;
39
-	}
40
-	
41
-	public BarHandle openContentBar(IDEAspectToolbar toolbar) {
42
-		listeners.accept(listener -> listener.onOpenContextBar(toolbar));
43
-		return new BarHandle(toolbar);
44
-	}
45
-	
46
-	private int insertToolbar(IDEAspectToolbar toolbar) {
47
-		for (int i = 0; i < aspectToolbars.size(); i++) {
48
-			if (toolbar.order < aspectToolbars.get(i).order) {
49
-				aspectToolbars.add(i, toolbar);
50
-				return i;
51
-			}
52
-		}
53
-		int index = aspectToolbars.size();
54
-		aspectToolbars.add(toolbar);
55
-		return index;
56
-	}
57
-	
58
-	public class BarHandle implements Closeable {
59
-		private final IDEAspectToolbar toolbar;
60
-		
61
-		public BarHandle(IDEAspectToolbar toolbar) {
62
-			this.toolbar = toolbar;
63
-		}
64
-		
65
-		@Override
66
-		public void close() {
67
-			listeners.accept(listener -> listener.onCloseContextBar(toolbar));
68
-		}
69
-	}
70
-	
71
-	public interface Listener {
72
-		void onAspectBarAdded(int index, IDEAspectToolbar toolbar);
73
-		void onAspectBarRemoved(int index, IDEAspectToolbar toolbar);
74
-		void onOpenContextBar(IDEAspectToolbar toolbar);
75
-		void onCloseContextBar(IDEAspectToolbar toolbar);
76
-	}
18
+	public final LiveList<IDEAspectToolbar> toolbars = new LiveArrayList<>(); // TODO: only expose read-only variant
19
+	public final LiveObject<IDEAspectToolbar> active = new SimpleLiveObject<>(null);
77 20
 }

+ 15
- 3
IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEDockWindow.java Visa fil

@@ -5,8 +5,8 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.ui;
7 7
 
8
-import org.openzen.drawablegui.live.LiveObject;
9
-import org.openzen.drawablegui.live.SimpleLiveObject;
8
+import org.openzen.drawablegui.listeners.ListenerHandle;
9
+import org.openzen.drawablegui.listeners.ListenerList;
10 10
 import org.openzen.zenscript.ide.host.IDESourceFile;
11 11
 
12 12
 /**
@@ -14,5 +14,17 @@ import org.openzen.zenscript.ide.host.IDESourceFile;
14 14
  * @author Hoofdgebruiker
15 15
  */
16 16
 public class IDEDockWindow {
17
-	public final LiveObject<IDESourceFile> currentSourceFile = new SimpleLiveObject<>(null);
17
+	private final ListenerList<Listener> listeners = new ListenerList<>();
18
+	
19
+	public ListenerHandle<Listener> addListener(Listener listener) {
20
+		return listeners.add(listener);
21
+	}
22
+	
23
+	public void open(IDESourceFile sourceFile) {
24
+		listeners.accept(listener -> listener.onOpen(sourceFile));
25
+	}
26
+	
27
+	public interface Listener {
28
+		void onOpen(IDESourceFile sourceFile);
29
+	}
18 30
 }

+ 12
- 5
IDE/src/main/java/org/openzen/zenscript/ide/ui/IDEWindow.java Visa fil

@@ -9,8 +9,11 @@ import org.openzen.drawablegui.live.SimpleLiveBool;
9 9
 import org.openzen.drawablegui.style.DStyleClass;
10 10
 import org.openzen.zenscript.ide.host.IDESourceFile;
11 11
 import org.openzen.zenscript.ide.ui.icons.AddBoxIcon;
12
+import org.openzen.zenscript.ide.ui.icons.BuildIcon;
13
+import org.openzen.zenscript.ide.ui.icons.PlayIcon;
12 14
 import org.openzen.zenscript.ide.ui.icons.ProjectIcon;
13 15
 import org.openzen.zenscript.ide.ui.icons.SettingsIcon;
16
+import org.openzen.zenscript.ide.ui.icons.ShadedProjectIcon;
14 17
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
15 18
 
16 19
 /**
@@ -22,6 +25,8 @@ public class IDEWindow {
22 25
 	public final IDEDockWindow dockWindow;
23 26
 	public final IDEStatusBar statusBar;
24 27
 	
28
+	public IDEAspectToolbar projectToolbar;
29
+	
25 30
 	public IDEWindow() {
26 31
 		aspectBar = new IDEAspectBar();
27 32
 		dockWindow = new IDEDockWindow();
@@ -37,13 +42,15 @@ public class IDEWindow {
37 42
 	}
38 43
 	
39 44
 	public void open(IDESourceFile sourceFile) {
40
-		dockWindow.currentSourceFile.setValue(sourceFile);
45
+		dockWindow.open(sourceFile);
41 46
 	}
42 47
 	
43 48
 	private void init() {
44
-		IDEAspectToolbar projectToolbar = new IDEAspectToolbar(0, ProjectIcon.GREY, "Project", "Project management");
45
-		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, AddBoxIcon.BLACK, e -> {}));
46
-		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, SettingsIcon.BLACK, e -> {}));
47
-		aspectBar.addToolbar(projectToolbar);
49
+		projectToolbar = new IDEAspectToolbar(0, ShadedProjectIcon.PURPLE, "Project", "Project management");
50
+		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, AddBoxIcon.ORANGE, e -> {}));
51
+		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, SettingsIcon.PURPLE, e -> {}));
52
+		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, BuildIcon.BLUE, e -> {}));
53
+		projectToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, PlayIcon.GREEN, e -> {}));
54
+		aspectBar.toolbars.add(projectToolbar);
48 55
 	}
49 56
 }

+ 5
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/AddBoxIcon.java Visa fil

@@ -8,10 +8,14 @@ import org.openzen.drawablegui.DCanvas;
8 8
 import org.openzen.drawablegui.DPath;
9 9
 import org.openzen.drawablegui.DTransform2D;
10 10
 import org.openzen.drawablegui.DColorableIcon;
11
+import org.openzen.drawablegui.style.DShadow;
11 12
 
12 13
 public class AddBoxIcon implements DColorableIcon {
13 14
 	public static final AddBoxIcon INSTANCE = new AddBoxIcon();
14 15
 	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
16
+	public static final ColoredIcon BLUE = new ColoredIcon(INSTANCE, 0xFF1B1464);
17
+	public static final ColoredIcon GREEN = new ColoredIcon(INSTANCE, 0xFF006266);
18
+	public static final ColoredIcon ORANGE = new ColoredIcon(INSTANCE, 0xFFEE5A24);
15 19
 	
16 20
 	private AddBoxIcon() {}
17 21
 	
@@ -44,6 +48,7 @@ public class AddBoxIcon implements DColorableIcon {
44 48
 	
45 49
 	@Override
46 50
 	public void draw(DCanvas canvas, DTransform2D transform, int color) {
51
+		canvas.shadowPath(PATH, transform, new DShadow(0xFF999999, 0, 1, 6));
47 52
 		canvas.fillPath(PATH, transform, color);
48 53
 	}
49 54
 

+ 52
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/BuildIcon.java Visa fil

@@ -0,0 +1,52 @@
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.icons;
7
+import org.openzen.drawablegui.DCanvas;
8
+import org.openzen.drawablegui.DPath;
9
+import org.openzen.drawablegui.DTransform2D;
10
+import org.openzen.drawablegui.DColorableIcon;
11
+import org.openzen.drawablegui.style.DShadow;
12
+
13
+public class BuildIcon implements DColorableIcon {
14
+	public static final BuildIcon INSTANCE = new BuildIcon();
15
+	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
16
+	public static final ColoredIcon BLUE = new ColoredIcon(INSTANCE, 0xFF0652DD);
17
+	
18
+	private BuildIcon() {}
19
+	
20
+	private static final DPath PATH = tracer -> {
21
+		tracer.moveTo(22.7f, 19f);
22
+		tracer.lineTo(13.6f, 9.9f);
23
+		tracer.bezierCubic(14.5f, 7.5999994f, 14.0f, 4.8999996f, 12.1f, 2.9999995f);
24
+		tracer.bezierCubic(10.1f, 0.9999995f, 7.1000004f, 0.5999994f, 4.7000003f, 1.6999996f);
25
+		tracer.lineTo(9f, 6f);
26
+		tracer.lineTo(6f, 9f);
27
+		tracer.lineTo(1.6f, 4.7f);
28
+		tracer.bezierCubic(0.4f, 7.1f, 0.9f, 10.1f, 2.9f, 12.1f);
29
+		tracer.bezierCubic(4.8f, 14.0f, 7.5f, 14.5f, 9.8f, 13.6f);
30
+		tracer.lineTo(18.900002f, 22.7f);
31
+		tracer.bezierCubic(19.300001f, 23.1f, 19.900002f, 23.1f, 20.300001f, 22.7f);
32
+		tracer.lineTo(22.6f, 20.400002f);
33
+		tracer.bezierCubic(23.1f, 20.000002f, 23.1f, 19.300001f, 22.7f, 19.000002f);
34
+		tracer.close();
35
+	};
36
+	
37
+	@Override
38
+	public void draw(DCanvas canvas, DTransform2D transform, int color) {
39
+		canvas.shadowPath(PATH, transform, new DShadow(0xFFCCCCCC, 0, 1, 4));
40
+		canvas.fillPath(PATH, transform, color);
41
+	}
42
+
43
+	@Override
44
+	public float getNominalWidth() {
45
+		return 24;
46
+	}
47
+
48
+	@Override
49
+	public float getNominalHeight() {
50
+		return 24;
51
+	}
52
+}

+ 42
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/PlayIcon.java Visa fil

@@ -0,0 +1,42 @@
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.icons;
7
+import org.openzen.drawablegui.DCanvas;
8
+import org.openzen.drawablegui.DPath;
9
+import org.openzen.drawablegui.DTransform2D;
10
+import org.openzen.drawablegui.DColorableIcon;
11
+import org.openzen.drawablegui.style.DShadow;
12
+
13
+public class PlayIcon implements DColorableIcon {
14
+	public static final PlayIcon INSTANCE = new PlayIcon();
15
+	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
16
+	public static final ColoredIcon GREEN = new ColoredIcon(INSTANCE, 0xFF009432);
17
+	
18
+	private PlayIcon() {}
19
+	
20
+	private static final DPath PATH = tracer -> {
21
+		tracer.moveTo(8f, 5f);
22
+		tracer.lineTo(8.0f, 19.0f);
23
+		tracer.lineTo(19.0f, 12.0f);
24
+		tracer.close();
25
+	};
26
+	
27
+	@Override
28
+	public void draw(DCanvas canvas, DTransform2D transform, int color) {
29
+		canvas.shadowPath(PATH, transform, new DShadow(0xFFCCCCCC, 0, 1, 4));
30
+		canvas.fillPath(PATH, transform, color);
31
+	}
32
+
33
+	@Override
34
+	public float getNominalWidth() {
35
+		return 24;
36
+	}
37
+
38
+	@Override
39
+	public float getNominalHeight() {
40
+		return 24;
41
+	}
42
+}

+ 2
- 1
IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/SettingsIcon.java Visa fil

@@ -13,6 +13,7 @@ import org.openzen.drawablegui.style.DShadow;
13 13
 public class SettingsIcon implements DColorableIcon {
14 14
 	public static final SettingsIcon INSTANCE = new SettingsIcon();
15 15
 	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
16
+	public static final ColoredIcon PURPLE = new ColoredIcon(INSTANCE, 0xFF5758BB);
16 17
 	
17 18
 	private SettingsIcon() {}
18 19
 	
@@ -67,7 +68,7 @@ public class SettingsIcon implements DColorableIcon {
67 68
 	
68 69
 	@Override
69 70
 	public void draw(DCanvas canvas, DTransform2D transform, int color) {
70
-		//canvas.shadowPath(PATH, transform, new DShadow(0xFF888888, 0, 1, 3.5f));
71
+		canvas.shadowPath(PATH, transform, new DShadow(0xFF888888, 0, 1, 4));
71 72
 		canvas.fillPath(PATH, transform, color);
72 73
 	}
73 74
 

+ 53
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/ShadedCodeIcon.java Visa fil

@@ -0,0 +1,53 @@
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.icons;
7
+
8
+import org.openzen.drawablegui.DCanvas;
9
+import org.openzen.drawablegui.DPath;
10
+import org.openzen.drawablegui.DTransform2D;
11
+import org.openzen.drawablegui.DColorableIcon;
12
+
13
+public class ShadedCodeIcon implements DColorableIcon {
14
+	public static final ShadedCodeIcon INSTANCE = new ShadedCodeIcon();
15
+	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
16
+	public static final ColoredIcon BLUE = new ColoredIcon(INSTANCE, 0xFF1B1464);
17
+	
18
+	private ShadedCodeIcon() {}
19
+	
20
+	private static final DPath PATH = tracer -> {
21
+		tracer.moveTo(9.4f, 16.6f);
22
+		tracer.lineTo(4.8f, 12f);
23
+		tracer.lineTo(9.4f, 7.4f);
24
+		tracer.lineTo(8f, 6f);
25
+		tracer.lineTo(2.0f, 12.0f);
26
+		tracer.lineTo(8.0f, 18.0f);
27
+		tracer.lineTo(9.4f, 16.6f);
28
+		tracer.close();
29
+		tracer.moveTo(14.599999f, 16.6f);
30
+		tracer.lineTo(19.199999f, 12.0f);
31
+		tracer.lineTo(14.599998f, 7.4f);
32
+		tracer.lineTo(16f, 6f);
33
+		tracer.lineTo(22.0f, 12.0f);
34
+		tracer.lineTo(16.0f, 18.0f);
35
+		tracer.lineTo(14.6f, 16.6f);
36
+		tracer.close();
37
+	};
38
+	
39
+	@Override
40
+	public void draw(DCanvas canvas, DTransform2D transform, int color) {
41
+		canvas.fillPath(PATH, transform, color);
42
+	}
43
+
44
+	@Override
45
+	public float getNominalWidth() {
46
+		return 24;
47
+	}
48
+
49
+	@Override
50
+	public float getNominalHeight() {
51
+		return 24;
52
+	}
53
+}

+ 61
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/ShadedProjectIcon.java Visa fil

@@ -0,0 +1,61 @@
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.icons;
7
+
8
+import org.openzen.drawablegui.DCanvas;
9
+import org.openzen.drawablegui.DPath;
10
+import org.openzen.drawablegui.DTransform2D;
11
+import org.openzen.drawablegui.DColorableIcon;
12
+
13
+public class ShadedProjectIcon implements DColorableIcon {
14
+	public static final ShadedProjectIcon INSTANCE = new ShadedProjectIcon();
15
+	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
16
+	public static final ColoredIcon PURPLE = new ColoredIcon(INSTANCE, 0xFF5758BB);
17
+	
18
+	private ShadedProjectIcon() {}
19
+	
20
+	private static final DPath PATH = tracer -> {
21
+		tracer.moveTo(3f, 13f);
22
+		tracer.lineTo(11.0f, 13.0f);
23
+		tracer.lineTo(11.0f, 3.0f);
24
+		tracer.lineTo(3.0f, 3.0f);
25
+		tracer.lineTo(3.0f, 13.0f);
26
+		tracer.close();
27
+		tracer.moveTo(3.0f, 21.0f);
28
+		tracer.lineTo(11.0f, 21.0f);
29
+		tracer.lineTo(11.0f, 15.0f);
30
+		tracer.lineTo(3.0f, 15.0f);
31
+		tracer.lineTo(3.0f, 21.0f);
32
+		tracer.close();
33
+		tracer.moveTo(13.0f, 21.0f);
34
+		tracer.lineTo(21.0f, 21.0f);
35
+		tracer.lineTo(21.0f, 11.0f);
36
+		tracer.lineTo(13.0f, 11.0f);
37
+		tracer.lineTo(13.0f, 21.0f);
38
+		tracer.close();
39
+		tracer.moveTo(13.0f, 3.0f);
40
+		tracer.lineTo(13.0f, 9.0f);
41
+		tracer.lineTo(21.0f, 9.0f);
42
+		tracer.lineTo(21.0f, 3.0f);
43
+		tracer.lineTo(13.0f, 3.0f);
44
+		tracer.close();
45
+	};
46
+	
47
+	@Override
48
+	public void draw(DCanvas canvas, DTransform2D transform, int color) {
49
+		canvas.fillPath(PATH, transform, color);
50
+	}
51
+
52
+	@Override
53
+	public float getNominalWidth() {
54
+		return 24;
55
+	}
56
+
57
+	@Override
58
+	public float getNominalHeight() {
59
+		return 24;
60
+	}
61
+}

+ 61
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/icons/ShadedSaveIcon.java Visa fil

@@ -0,0 +1,61 @@
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.icons;
7
+
8
+import org.openzen.drawablegui.DCanvas;
9
+import org.openzen.drawablegui.DPath;
10
+import org.openzen.drawablegui.DTransform2D;
11
+import org.openzen.drawablegui.DColorableIcon;
12
+import org.openzen.drawablegui.style.DShadow;
13
+
14
+public class ShadedSaveIcon implements DColorableIcon {
15
+	public static final ShadedSaveIcon INSTANCE = new ShadedSaveIcon();
16
+	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
17
+	public static final ColoredIcon PURPLE = new ColoredIcon(INSTANCE, 0xFF5758BB);
18
+	
19
+	private ShadedSaveIcon() {}
20
+	
21
+	private static final DPath PATH = tracer -> {
22
+		tracer.moveTo(17f, 3f);
23
+		tracer.lineTo(5.0f, 3.0f);
24
+		tracer.bezierCubic(3.8899999f, 3.0f, 3.0f, 3.9f, 3.0f, 5.0f);
25
+		tracer.lineTo(3.0f, 19.0f);
26
+		tracer.bezierCubic(3.0f, 20.1f, 3.8899999f, 21.0f, 5.0f, 21.0f);
27
+		tracer.lineTo(19.0f, 21.0f);
28
+		tracer.bezierCubic(20.1f, 21.0f, 21.0f, 20.1f, 21.0f, 19.0f);
29
+		tracer.lineTo(21.0f, 7.0f);
30
+		tracer.lineTo(17.0f, 3.0f);
31
+		tracer.close();
32
+		tracer.moveTo(12.0f, 19.0f);
33
+		tracer.bezierCubic(10.34f, 19.0f, 9.0f, 17.66f, 9.0f, 16.0f);
34
+		tracer.bezierCubic(9.0f, 14.34f, 10.34f, 13.0f, 12.0f, 13.0f);
35
+		tracer.bezierCubic(13.66f, 13.0f, 15.0f, 14.34f, 15.0f, 16.0f);
36
+		tracer.bezierCubic(15.0f, 17.66f, 13.66f, 19.0f, 12.0f, 19.0f);
37
+		tracer.close();
38
+		tracer.moveTo(15.0f, 9.0f);
39
+		tracer.lineTo(5.0f, 9.0f);
40
+		tracer.lineTo(5.0f, 5.0f);
41
+		tracer.lineTo(15.0f, 5.0f);
42
+		tracer.lineTo(15.0f, 9.0f);
43
+		tracer.close();
44
+	};
45
+	
46
+	@Override
47
+	public void draw(DCanvas canvas, DTransform2D transform, int color) {
48
+		canvas.shadowPath(PATH, transform, new DShadow(0xFFCCCCCC, 0, 1, 4));
49
+		canvas.fillPath(PATH, transform, color);
50
+	}
51
+
52
+	@Override
53
+	public float getNominalWidth() {
54
+		return 24;
55
+	}
56
+
57
+	@Override
58
+	public float getNominalHeight() {
59
+		return 24;
60
+	}
61
+}

+ 1
- 1
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/IconButtonControl.java Visa fil

@@ -14,7 +14,7 @@ import org.openzen.drawablegui.DMouseEvent;
14 14
 import org.openzen.drawablegui.DPath;
15 15
 import org.openzen.drawablegui.DTransform2D;
16 16
 import org.openzen.drawablegui.DUIContext;
17
-import org.openzen.drawablegui.listeners.DIRectangle;
17
+import org.openzen.drawablegui.DIRectangle;
18 18
 import org.openzen.drawablegui.listeners.ListenerHandle;
19 19
 import org.openzen.drawablegui.live.ImmutableLiveBool;
20 20
 import org.openzen.drawablegui.live.LiveBool;

+ 1
- 1
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/StatusBarView.java Visa fil

@@ -8,7 +8,7 @@ package org.openzen.zenscript.ide.ui.view;
8 8
 import org.openzen.drawablegui.DCanvas;
9 9
 import org.openzen.drawablegui.DComponent;
10 10
 import org.openzen.drawablegui.DDimensionPreferences;
11
-import org.openzen.drawablegui.listeners.DIRectangle;
11
+import org.openzen.drawablegui.DIRectangle;
12 12
 import org.openzen.drawablegui.live.LiveObject;
13 13
 import org.openzen.drawablegui.live.SimpleLiveObject;
14 14
 import org.openzen.drawablegui.DUIContext;

+ 197
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedView.java Visa fil

@@ -0,0 +1,197 @@
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;
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.DDimensionPreferences;
14
+import org.openzen.drawablegui.DFontMetrics;
15
+import org.openzen.drawablegui.DIRectangle;
16
+import org.openzen.drawablegui.DPath;
17
+import org.openzen.drawablegui.DTransform2D;
18
+import org.openzen.drawablegui.DUIContext;
19
+import org.openzen.drawablegui.live.ImmutableLiveObject;
20
+import org.openzen.drawablegui.live.LiveArrayList;
21
+import org.openzen.drawablegui.live.LiveList;
22
+import org.openzen.drawablegui.live.LiveMappedList;
23
+import org.openzen.drawablegui.live.LiveObject;
24
+import org.openzen.drawablegui.live.SimpleLiveObject;
25
+import org.openzen.drawablegui.style.DStyleClass;
26
+import org.openzen.drawablegui.style.DStylePath;
27
+
28
+/**
29
+ *
30
+ * @author Hoofdgebruiker
31
+ */
32
+public class TabbedView extends BaseComponentGroup {
33
+	private final DStyleClass styleClass;
34
+	public final LiveList<TabbedViewComponent> tabs = new LiveArrayList<>();
35
+	private final LiveObject<DDimensionPreferences> preferences = new ImmutableLiveObject<>(DDimensionPreferences.EMPTY);
36
+	public final LiveObject<TabbedViewComponent> currentTab = new SimpleLiveObject<>(null);
37
+	
38
+	private DUIContext context;
39
+	private DStylePath path;
40
+	private DIRectangle bounds;
41
+	private TabbedViewStyle style;
42
+	private int totalTabHeight;
43
+	private DFontMetrics fontMetrics;
44
+
45
+	private final LiveList<TabbedViewTab> tabComponents = new LiveMappedList<>(tabs, tab -> {
46
+		TabbedViewTab result = new TabbedViewTab(this, currentTab, tab);
47
+		if (context != null)
48
+			result.setContext(path, context);
49
+		return result;
50
+	});
51
+	
52
+	public TabbedView(DStyleClass styleClass) {
53
+		this.styleClass = styleClass;
54
+		tabs.addListener(new TabListListener());
55
+		
56
+		currentTab.addListener((oldValue, newValue) -> {
57
+			if (oldValue != null)
58
+				oldValue.content.onUnmounted();
59
+			if (newValue != null)
60
+				newValue.content.onMounted();
61
+			
62
+			if (newValue != null && bounds != null) {
63
+				DIRectangle contentBounds = new DIRectangle(
64
+					bounds.x, bounds.y + totalTabHeight,
65
+					bounds.width, bounds.height - totalTabHeight);
66
+				newValue.content.setBounds(contentBounds);
67
+			}
68
+		});
69
+	}
70
+	
71
+	@Override
72
+	public void setContext(DStylePath parent, DUIContext context) {
73
+		this.context = context;
74
+		path = parent.getChild("tabbedView", styleClass);
75
+		style = new TabbedViewStyle(context.getStylesheets().get(context, path));
76
+		fontMetrics = context.getFontMetrics(style.tabFont);
77
+		totalTabHeight = style.paddingTop + style.paddingBottom + fontMetrics.getAscent() + fontMetrics.getDescent();
78
+		
79
+		for (TabbedViewComponent tab : tabs)
80
+			prepare(tab);
81
+	}
82
+
83
+	@Override
84
+	public LiveObject<DDimensionPreferences> getDimensionPreferences() {
85
+		return preferences;
86
+	}
87
+
88
+	@Override
89
+	public DIRectangle getBounds() {
90
+		return bounds;
91
+	}
92
+
93
+	@Override
94
+	public void setBounds(DIRectangle bounds) {
95
+		this.bounds = bounds;
96
+		
97
+		if (currentTab.getValue() == null)
98
+			return;
99
+		
100
+		DIRectangle contentBounds = new DIRectangle(
101
+				bounds.x, bounds.y + totalTabHeight,
102
+				bounds.width, bounds.height - totalTabHeight);
103
+		currentTab.getValue().content.setBounds(contentBounds);
104
+		layoutTabs();
105
+	}
106
+
107
+	@Override
108
+	public void paint(DCanvas canvas) {
109
+		for (DComponent component : tabComponents)
110
+			component.paint(canvas);
111
+		
112
+		if (currentTab.getValue() != null)
113
+			currentTab.getValue().content.paint(canvas);
114
+	}
115
+
116
+	@Override
117
+	public void close() {
118
+		
119
+	}
120
+	
121
+	private void repaintTabs() {
122
+		if (context == null)
123
+			return;
124
+		
125
+		context.repaint(bounds.x, bounds.y, bounds.width, totalTabHeight);
126
+	}
127
+	
128
+	private void prepare(TabbedViewComponent tab) {
129
+		tab.content.setContext(path, context);
130
+	}
131
+	
132
+	private void layoutTabs() {
133
+		if (bounds == null)
134
+			return;
135
+		
136
+		int x = bounds.x + style.tabBarSpacingLeft;
137
+		for (DComponent tab : tabComponents) {
138
+			DDimensionPreferences preferences = tab.getDimensionPreferences().getValue();
139
+			tab.setBounds(new DIRectangle(
140
+					x, bounds.y + totalTabHeight - preferences.preferredHeight, preferences.preferredWidth, preferences.preferredHeight));
141
+			
142
+			x += preferences.preferredWidth + style.tabSpacing;
143
+		}
144
+		
145
+		repaintTabs();
146
+	}
147
+
148
+	@Override
149
+	protected void forEachChild(Consumer<DComponent> children) {
150
+		if (currentTab.getValue() != null)
151
+			children.accept(currentTab.getValue().content);
152
+		
153
+		for (TabbedViewTab component : tabComponents)
154
+			children.accept(component.closeButton);
155
+		for (TabbedViewTab component : tabComponents)
156
+			children.accept(component);
157
+	}
158
+
159
+	@Override
160
+	protected DComponent findChild(Predicate<DComponent> predicate) {
161
+		if (currentTab.getValue() != null && predicate.test(currentTab.getValue().content))
162
+			return currentTab.getValue().content;
163
+		
164
+		for (TabbedViewTab component : tabComponents)
165
+			if (predicate.test(component.closeButton))
166
+				return component.closeButton;
167
+		for (TabbedViewTab component : tabComponents)
168
+			if (predicate.test(component))
169
+				return component;
170
+		
171
+		return null;
172
+	}
173
+	
174
+	private class TabListListener implements LiveList.Listener<TabbedViewComponent> {
175
+		@Override
176
+		public void onInserted(int index, TabbedViewComponent value) {
177
+			if (currentTab.getValue() == null)
178
+				currentTab.setValue(value);
179
+			
180
+			prepare(value);
181
+			layoutTabs();
182
+		}
183
+
184
+		@Override
185
+		public void onChanged(int index, TabbedViewComponent oldValue, TabbedViewComponent newValue) {
186
+			repaintTabs();
187
+		}
188
+
189
+		@Override
190
+		public void onRemoved(int index, TabbedViewComponent oldValue) {
191
+			if (oldValue == currentTab.getValue())
192
+				currentTab.setValue(tabs.size() == 0 ? null : tabs.get(Math.max(index - 1, 0)));
193
+			
194
+			layoutTabs();
195
+		}
196
+	}
197
+}

+ 25
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewComponent.java Visa fil

@@ -0,0 +1,25 @@
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;
7
+
8
+import org.openzen.drawablegui.DComponent;
9
+import org.openzen.drawablegui.DDrawable;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class TabbedViewComponent {
16
+	public final String title;
17
+	public final DDrawable icon;
18
+	public final DComponent content;
19
+	
20
+	public TabbedViewComponent(String title, DDrawable icon, DComponent content) {
21
+		this.title = title;
22
+		this.icon = icon;
23
+		this.content = content;
24
+	}
25
+}

+ 60
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewStyle.java Visa fil

@@ -0,0 +1,60 @@
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;
7
+
8
+import org.openzen.drawablegui.DFont;
9
+import org.openzen.drawablegui.DFontFamily;
10
+import org.openzen.drawablegui.style.DDpDimension;
11
+import org.openzen.drawablegui.style.DPxDimension;
12
+import org.openzen.drawablegui.style.DStyleDefinition;
13
+
14
+/**
15
+ *
16
+ * @author Hoofdgebruiker
17
+ */
18
+public class TabbedViewStyle {
19
+	public final int backgroundColor;
20
+	public final DFont tabFont;
21
+	public final int tabFontColor;
22
+	
23
+	public final int tabColorNormal;
24
+	public final int tabColorHover;
25
+	public final int tabColorPress;
26
+	public final int tabColorActive;
27
+	
28
+	public final int paddingTop;
29
+	public final int paddingBottom;
30
+	public final int paddingLeft;
31
+	public final int paddingRight;
32
+	public final int tabBarSpacingLeft;
33
+	public final int tabBarSpacingRight;
34
+	public final int tabSpacing;
35
+	
36
+	public final int borderColor;
37
+	public final int borderWidth;
38
+	
39
+	public TabbedViewStyle(DStyleDefinition style) {
40
+		backgroundColor = style.getColor("backgroundColor", 0xFFEEEEEE);
41
+		tabFont = style.getFont("tabFont", context -> new DFont(DFontFamily.CODE, false, false, false, (int)(12 * context.getScale())));
42
+		tabFontColor = style.getColor("tabFontColor", 0xFF000000);
43
+		
44
+		tabColorNormal = style.getColor("tabColorNormal", 0xFFEEEEEE);
45
+		tabColorHover = style.getColor("tabColorHover", 0xFFFFFFFF);
46
+		tabColorPress = style.getColor("tabColorPress", 0xFFF0F0F0);
47
+		tabColorActive = style.getColor("tabColorActive", 0xFFFFFFFF);
48
+		
49
+		paddingTop = style.getDimension("paddingTop", new DDpDimension(4));
50
+		paddingBottom = style.getDimension("paddingTop", new DDpDimension(4));
51
+		paddingLeft = style.getDimension("paddingLeft", new DDpDimension(4));
52
+		paddingRight = style.getDimension("paddingRight", new DDpDimension(4));
53
+		tabBarSpacingLeft = style.getDimension("tabBarSpacingLeft", new DDpDimension(4));
54
+		tabBarSpacingRight = style.getDimension("tabBarSpacingRight", new DDpDimension(4));
55
+		tabSpacing = style.getDimension("tabSpacing", new DDpDimension(4));
56
+		
57
+		borderColor = style.getColor("borderColor", 0xFF888888);
58
+		borderWidth = style.getDimension("borderWidth", new DPxDimension(1));
59
+	}
60
+}

+ 153
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTab.java Visa fil

@@ -0,0 +1,153 @@
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;
7
+
8
+import org.openzen.drawablegui.DCanvas;
9
+import org.openzen.drawablegui.DComponent;
10
+import org.openzen.drawablegui.DDimensionPreferences;
11
+import org.openzen.drawablegui.DFontMetrics;
12
+import org.openzen.drawablegui.DIRectangle;
13
+import org.openzen.drawablegui.DMouseEvent;
14
+import org.openzen.drawablegui.DPath;
15
+import org.openzen.drawablegui.DTransform2D;
16
+import org.openzen.drawablegui.DUIContext;
17
+import org.openzen.drawablegui.live.LiveObject;
18
+import org.openzen.drawablegui.live.SimpleLiveObject;
19
+import org.openzen.drawablegui.style.DStyleClass;
20
+import org.openzen.drawablegui.style.DStylePath;
21
+
22
+/**
23
+ *
24
+ * @author Hoofdgebruiker
25
+ */
26
+public class TabbedViewTab implements DComponent {
27
+	private final TabbedViewComponent tab;
28
+	private final LiveObject<DDimensionPreferences> preferences = new SimpleLiveObject<>(DDimensionPreferences.EMPTY);
29
+	private final LiveObject<TabbedViewComponent> currentTab;
30
+	
31
+	private final TabbedView parent;
32
+	public final TabbedViewTabClose closeButton;
33
+	
34
+	private DUIContext context;
35
+	private TabbedViewTabStyle style;
36
+	private DFontMetrics fontMetrics;
37
+	private int textWidth;
38
+	private DIRectangle bounds;
39
+	
40
+	private boolean hover;
41
+	private boolean press;
42
+	
43
+	public TabbedViewTab(TabbedView parent, LiveObject<TabbedViewComponent> currentTab, TabbedViewComponent tab) {
44
+		this.parent = parent;
45
+		this.currentTab = currentTab;
46
+		this.tab = tab;
47
+		this.closeButton = new TabbedViewTabClose(this);
48
+	}
49
+	
50
+	public void closeTab() {
51
+		parent.tabs.remove(tab);
52
+	}
53
+
54
+	@Override
55
+	public void setContext(DStylePath parent, DUIContext context) {
56
+		this.context = context;
57
+		DStylePath path = parent.getChild("tab", DStyleClass.EMPTY);
58
+		style = new TabbedViewTabStyle(context.getStylesheets().get(context, path));
59
+		fontMetrics = context.getFontMetrics(style.tabFont);
60
+		closeButton.setContext(path, context);
61
+		
62
+		textWidth = fontMetrics.getWidth(tab.title);
63
+		preferences.setValue(new DDimensionPreferences(
64
+				style.paddingLeft + textWidth + style.paddingRight
65
+						+ style.closeIconPadding
66
+						+ closeButton.getDimensionPreferences().getValue().preferredWidth,
67
+				style.paddingTop + fontMetrics.getAscent() + fontMetrics.getDescent()
68
+						+ style.paddingBottom));
69
+	}
70
+
71
+	@Override
72
+	public LiveObject<DDimensionPreferences> getDimensionPreferences() {
73
+		return preferences;
74
+	}
75
+
76
+	@Override
77
+	public DIRectangle getBounds() {
78
+		return bounds;
79
+	}
80
+
81
+	@Override
82
+	public void setBounds(DIRectangle bounds) {
83
+		this.bounds = bounds;
84
+		
85
+		DDimensionPreferences close = closeButton.getDimensionPreferences().getValue();
86
+		closeButton.setBounds(new DIRectangle(
87
+				bounds.x + bounds.width - close.preferredWidth - style.paddingRight,
88
+				bounds.y + (bounds.height - close.preferredHeight) / 2,
89
+				close.preferredWidth,
90
+				close.preferredHeight));
91
+	}
92
+
93
+	@Override
94
+	public void paint(DCanvas canvas) {
95
+		int width = style.paddingLeft + textWidth + style.paddingRight
96
+				+ closeButton.getDimensionPreferences().getValue().preferredWidth + style.closeIconPadding;
97
+
98
+		int color = style.tabColorNormal;
99
+		if (currentTab.getValue() == tab)
100
+			color = style.tabColorActive;
101
+		else if (press)
102
+			color = style.tabColorPress;
103
+		else if (hover)
104
+			color = style.tabColorHover;
105
+
106
+		canvas.fillRectangle(bounds.x, bounds.y, width, bounds.height, color);
107
+		canvas.strokePath(DPath.rectangle(bounds.x, bounds.y, width, bounds.height), DTransform2D.IDENTITY, style.borderColor, style.borderWidth);
108
+
109
+		canvas.drawText(style.tabFont, style.tabFontColor, bounds.x + style.paddingLeft, bounds.y + style.paddingTop + fontMetrics.getAscent(), tab.title);
110
+		
111
+		closeButton.paint(canvas);
112
+	}
113
+
114
+	@Override
115
+	public void close() {
116
+		
117
+	}
118
+	
119
+	@Override
120
+	public void onMouseEnter(DMouseEvent e) {
121
+		hover = true;
122
+		repaint();
123
+	}
124
+	
125
+	@Override
126
+	public void onMouseExit(DMouseEvent e) {
127
+		hover = false;
128
+		press = false;
129
+		repaint();
130
+	}
131
+	
132
+	@Override
133
+	public void onMouseDown(DMouseEvent e) {
134
+		press = true;
135
+		repaint();
136
+	}
137
+	
138
+	@Override
139
+	public void onMouseRelease(DMouseEvent e) {
140
+		press = false;
141
+		repaint();
142
+	}
143
+	
144
+	@Override
145
+	public void onMouseClick(DMouseEvent e) {
146
+		currentTab.setValue(tab);
147
+	}
148
+	
149
+	private void repaint() {
150
+		if (context != null && bounds != null)
151
+			context.repaint(bounds);
152
+	}
153
+}

+ 102
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabClose.java Visa fil

@@ -0,0 +1,102 @@
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;
7
+
8
+import org.openzen.drawablegui.DCanvas;
9
+import org.openzen.drawablegui.DColorableIcon;
10
+import org.openzen.drawablegui.DComponent;
11
+import org.openzen.drawablegui.DDimensionPreferences;
12
+import org.openzen.drawablegui.DDrawable;
13
+import org.openzen.drawablegui.DIRectangle;
14
+import org.openzen.drawablegui.DMouseEvent;
15
+import org.openzen.drawablegui.DTransform2D;
16
+import org.openzen.drawablegui.DUIContext;
17
+import org.openzen.drawablegui.live.LiveObject;
18
+import org.openzen.drawablegui.live.SimpleLiveObject;
19
+import org.openzen.drawablegui.style.DStyleClass;
20
+import org.openzen.drawablegui.style.DStylePath;
21
+import org.openzen.zenscript.ide.ui.icons.ColoredIcon;
22
+import org.openzen.zenscript.ide.ui.icons.ScalableCloseIcon;
23
+
24
+/**
25
+ *
26
+ * @author Hoofdgebruiker
27
+ */
28
+public class TabbedViewTabClose implements DComponent {
29
+	private final TabbedViewTab tab;
30
+	private final LiveObject<DDimensionPreferences> preferences = new SimpleLiveObject<>(DDimensionPreferences.EMPTY);
31
+	
32
+	private DUIContext context;
33
+	private DIRectangle bounds;
34
+	private TabbedViewTabCloseStyle style;
35
+	private DColorableIcon icon;
36
+	
37
+	private boolean hover;
38
+	private boolean press;
39
+	
40
+	public TabbedViewTabClose(TabbedViewTab tab) {
41
+		this.tab = tab;
42
+	}
43
+
44
+	@Override
45
+	public void setContext(DStylePath parent, DUIContext context) {
46
+		this.context = context;
47
+		
48
+		DStylePath path = parent.getChild("tabClose", DStyleClass.EMPTY);
49
+		style = new TabbedViewTabCloseStyle(context.getStylesheets().get(context, path));
50
+		preferences.setValue(new DDimensionPreferences(style.size, style.size));
51
+		icon = new ScalableCloseIcon(style.size / 24);
52
+	}
53
+
54
+	@Override
55
+	public LiveObject<DDimensionPreferences> getDimensionPreferences() {
56
+		return preferences;
57
+	}
58
+
59
+	@Override
60
+	public DIRectangle getBounds() {
61
+		return bounds;
62
+	}
63
+
64
+	@Override
65
+	public void setBounds(DIRectangle bounds) {
66
+		this.bounds = bounds;
67
+	}
68
+
69
+	@Override
70
+	public void paint(DCanvas canvas) {
71
+		if (hover) {
72
+			canvas.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 0xFFE81123);
73
+		}
74
+		
75
+		icon.draw(canvas, DTransform2D.translate(
76
+				bounds.x + (bounds.width - icon.getNominalWidth()) / 2,
77
+				bounds.y + (bounds.height - icon.getNominalHeight()) / 2),
78
+				hover ? 0xFFFFFFFF : 0xFF000000);
79
+	}
80
+
81
+	@Override
82
+	public void close() {
83
+		
84
+	}
85
+	
86
+	@Override
87
+	public void onMouseEnter(DMouseEvent e) {
88
+		hover = true;
89
+		context.repaint(bounds);
90
+	}
91
+	
92
+	@Override
93
+	public void onMouseExit(DMouseEvent e) {
94
+		hover = false;
95
+		context.repaint(bounds);
96
+	}
97
+	
98
+	@Override
99
+	public void onMouseClick(DMouseEvent e) {
100
+		tab.closeTab();
101
+	}
102
+}

+ 21
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabCloseStyle.java Visa fil

@@ -0,0 +1,21 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.view;
7
+
8
+import org.openzen.drawablegui.style.DDpDimension;
9
+import org.openzen.drawablegui.style.DStyleDefinition;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class TabbedViewTabCloseStyle {
16
+	public final int size;
17
+	
18
+	public TabbedViewTabCloseStyle(DStyleDefinition style) {
19
+		size = style.getDimension("size", new DDpDimension(16));
20
+	}
21
+}

+ 58
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/TabbedViewTabStyle.java Visa fil

@@ -0,0 +1,58 @@
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;
7
+
8
+import org.openzen.drawablegui.DFont;
9
+import org.openzen.drawablegui.DFontFamily;
10
+import org.openzen.drawablegui.style.DDpDimension;
11
+import org.openzen.drawablegui.style.DPxDimension;
12
+import org.openzen.drawablegui.style.DStyleDefinition;
13
+
14
+/**
15
+ *
16
+ * @author Hoofdgebruiker
17
+ */
18
+public class TabbedViewTabStyle {
19
+	public final DFont tabFont;
20
+	public final int tabFontColor;
21
+	
22
+	public final int tabColorNormal;
23
+	public final int tabColorHover;
24
+	public final int tabColorPress;
25
+	public final int tabColorActive;
26
+	
27
+	public final int paddingTop;
28
+	public final int paddingBottom;
29
+	public final int paddingLeft;
30
+	public final int paddingRight;
31
+	
32
+	public final int borderColor;
33
+	public final int borderWidth;
34
+	
35
+	public final int closeIconSize;
36
+	public final int closeIconPadding;
37
+	
38
+	public TabbedViewTabStyle(DStyleDefinition style) {
39
+		tabFont = style.getFont("tabFont", context -> new DFont(DFontFamily.CODE, false, false, false, (int)(12 * context.getScale())));
40
+		tabFontColor = style.getColor("tabFontColor", 0xFF000000);
41
+		
42
+		tabColorNormal = style.getColor("tabColorNormal", 0xFFEEEEEE);
43
+		tabColorHover = style.getColor("tabColorHover", 0xFFFFFFFF);
44
+		tabColorPress = style.getColor("tabColorPress", 0xFFF0F0F0);
45
+		tabColorActive = style.getColor("tabColorActive", 0xFFFFFFFF);
46
+		
47
+		paddingTop = style.getDimension("paddingTop", new DDpDimension(4));
48
+		paddingBottom = style.getDimension("paddingTop", new DDpDimension(4));
49
+		paddingLeft = style.getDimension("paddingLeft", new DDpDimension(4));
50
+		paddingRight = style.getDimension("paddingRight", new DDpDimension(4));
51
+		
52
+		borderColor = style.getColor("borderColor", 0xFF888888);
53
+		borderWidth = style.getDimension("borderWidth", new DPxDimension(1));
54
+		
55
+		closeIconSize = style.getDimension("closeIconSize", new DDpDimension(16));
56
+		closeIconPadding = style.getDimension("closeIconPadding", new DDpDimension(6));
57
+	}
58
+}

+ 23
- 7
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/WindowView.java Visa fil

@@ -5,14 +5,19 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.ui.view;
7 7
 
8
+import org.openzen.drawablegui.DComponent;
8 9
 import org.openzen.drawablegui.DDimensionPreferences;
10
+import org.openzen.drawablegui.DDrawable;
9 11
 import org.openzen.drawablegui.DEmptyView;
10 12
 import org.openzen.drawablegui.scroll.DScrollPane;
11 13
 import org.openzen.drawablegui.DSideLayout;
14
+import org.openzen.drawablegui.live.LiveList;
12 15
 import org.openzen.drawablegui.style.DStyleClass;
13 16
 import org.openzen.drawablegui.tree.DTreeView;
14 17
 import org.openzen.drawablegui.tree.DTreeViewStyle;
15 18
 import org.openzen.zenscript.ide.host.DevelopmentHost;
19
+import org.openzen.zenscript.ide.host.IDESourceFile;
20
+import org.openzen.zenscript.ide.ui.IDEDockWindow;
16 21
 import org.openzen.zenscript.ide.ui.IDEWindow;
17 22
 import org.openzen.zenscript.ide.ui.view.aspectbar.AspectBarView;
18 23
 import org.openzen.zenscript.ide.ui.view.editor.SourceEditor;
@@ -23,21 +28,32 @@ import org.openzen.zenscript.ide.ui.view.project.RootTreeNode;
23 28
  * @author Hoofdgebruiker
24 29
  */
25 30
 public final class WindowView extends DSideLayout {
31
+	private final IDEWindow window;
32
+	private final TabbedView tabs;
33
+	
26 34
 	public WindowView(IDEWindow window, DevelopmentHost host) {
27 35
 		super(DStyleClass.EMPTY, DEmptyView.INSTANCE);
36
+		this.window = window;
28 37
 		
29 38
 		DTreeView projectView = new DTreeView(DTreeViewStyle.DEFAULT, new RootTreeNode(window, host), false);
30 39
 		projectView.getDimensionPreferences().setValue(new DDimensionPreferences(500, 500));
40
+		setMain(tabs = new TabbedView(DStyleClass.EMPTY));
31 41
 		add(Side.LEFT, new DScrollPane(DStyleClass.forId("projectView"), projectView));
32 42
 		add(Side.BOTTOM, new StatusBarView());
33 43
 		add(Side.TOP, new AspectBarView(DStyleClass.EMPTY, window.aspectBar));
34 44
 		
35
-		window.dockWindow.currentSourceFile.addListener((oldSource, newSource) -> {
36
-			if (newSource == null) {
37
-				setMain(DEmptyView.INSTANCE);
38
-			} else {
39
-				setMain(new DScrollPane(DStyleClass.EMPTY, new SourceEditor(DStyleClass.EMPTY, window, newSource)));
40
-			}
41
-		});
45
+		window.dockWindow.addListener(new DockWindowListener());
46
+	}
47
+	
48
+	private class DockWindowListener implements IDEDockWindow.Listener {
49
+		@Override
50
+		public void onOpen(IDESourceFile sourceFile) {
51
+			TabbedViewComponent tab = new TabbedViewComponent(
52
+					sourceFile.getName(),
53
+					null,
54
+					new DScrollPane(DStyleClass.EMPTY, new SourceEditor(DStyleClass.EMPTY, window, sourceFile)));
55
+			tabs.tabs.add(tab);
56
+			tabs.currentTab.setValue(tab);
57
+		}
42 58
 	}
43 59
 }

+ 4
- 4
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarSelectorButton.java Visa fil

@@ -14,7 +14,7 @@ import org.openzen.drawablegui.DMouseEvent;
14 14
 import org.openzen.drawablegui.DPath;
15 15
 import org.openzen.drawablegui.DTransform2D;
16 16
 import org.openzen.drawablegui.DUIContext;
17
-import org.openzen.drawablegui.listeners.DIRectangle;
17
+import org.openzen.drawablegui.DIRectangle;
18 18
 import org.openzen.drawablegui.listeners.ListenerHandle;
19 19
 import org.openzen.drawablegui.live.LiveBool;
20 20
 import org.openzen.drawablegui.live.LiveObject;
@@ -37,7 +37,7 @@ public class AspectBarSelectorButton implements DComponent {
37 37
 	private final Consumer<DMouseEvent> onClick;
38 38
 	private DUIContext context;
39 39
 	private AspectBarSelectorButtonStyle style;
40
-	private DIRectangle bounds;
40
+	private DIRectangle bounds = DIRectangle.EMPTY;
41 41
 	private DPath shape;
42 42
 	private boolean hovering;
43 43
 	private boolean pressing;
@@ -141,11 +141,11 @@ public class AspectBarSelectorButton implements DComponent {
141 141
 
142 142
 	@Override
143 143
 	public void close() {
144
-		// nothing
144
+		activeListener.close();
145 145
 	}
146 146
 	
147 147
 	private void repaint() {
148
-		if (context != null)
148
+		if (context != null && bounds != null)
149 149
 			context.repaint(bounds);
150 150
 	}
151 151
 }

+ 41
- 27
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/AspectBarView.java Visa fil

@@ -16,7 +16,7 @@ import org.openzen.drawablegui.DDimensionPreferences;
16 16
 import org.openzen.drawablegui.DFontMetrics;
17 17
 import org.openzen.drawablegui.DPath;
18 18
 import org.openzen.drawablegui.DTransform2D;
19
-import org.openzen.drawablegui.listeners.DIRectangle;
19
+import org.openzen.drawablegui.DIRectangle;
20 20
 import org.openzen.drawablegui.live.LiveObject;
21 21
 import org.openzen.drawablegui.live.SimpleLiveObject;
22 22
 import org.openzen.zenscript.ide.ui.IDEAspectBar;
@@ -28,11 +28,9 @@ import org.openzen.drawablegui.live.LiveBool;
28 28
 import org.openzen.drawablegui.live.LiveList;
29 29
 import org.openzen.drawablegui.live.LiveMappedList;
30 30
 import org.openzen.drawablegui.live.LivePredicateBool;
31
-import org.openzen.drawablegui.live.SimpleLiveBool;
32 31
 import org.openzen.drawablegui.style.DStyleClass;
33 32
 import org.openzen.drawablegui.style.DStylePath;
34 33
 import org.openzen.zenscript.ide.ui.IDEAspectBarControl;
35
-import org.openzen.zenscript.ide.ui.icons.CloseIcon;
36 34
 import org.openzen.zenscript.ide.ui.icons.ScalableCloseIcon;
37 35
 import org.openzen.zenscript.ide.ui.icons.ScalableMaximizeIcon;
38 36
 import org.openzen.zenscript.ide.ui.icons.ScalableMinimizeIcon;
@@ -55,7 +53,6 @@ public class AspectBarView extends BaseComponentGroup {
55 53
 	private boolean showWindowControls;
56 54
 	
57 55
 	private final LiveMappedList<IDEAspectToolbar, AspectBarSelectorButton> selectorButtons;
58
-	public final LiveObject<IDEAspectToolbar> active = new SimpleLiveObject<>(null);
59 56
 	private LiveMappedList<IDEAspectBarControl, DComponent> activeToolbarComponents;
60 57
 	
61 58
 	private final ListenerHandle<LiveList.Listener<IDEAspectToolbar>> listener;
@@ -75,8 +72,8 @@ public class AspectBarView extends BaseComponentGroup {
75 72
 		this.styleClass = styleClass;
76 73
 		this.aspectBar = aspectBar;
77 74
 		
78
-		active.addListener(this::onActiveChanged);
79
-		listener = aspectBar.aspectToolbars.addListener(new ToolbarListListener());
75
+		aspectBar.active.addListener(this::onActiveChanged);
76
+		listener = aspectBar.toolbars.addListener(new ToolbarListListener());
80 77
 		
81 78
 		minimize = new WindowActionButton(scale -> new ScalableMinimizeIcon(scale), e -> context.getWindow().minimize());
82 79
 		minimizeRelayout = minimize.getDimensionPreferences().addListener((a, b) -> layout());
@@ -91,18 +88,19 @@ public class AspectBarView extends BaseComponentGroup {
91 88
 		closeRelayout = close.getDimensionPreferences().addListener((a, b) -> layout());
92 89
 		
93 90
 		selectorButtons = new LiveMappedList<>(
94
-				aspectBar.aspectToolbars,
91
+				aspectBar.toolbars,
95 92
 				bar -> {
96
-					LiveBool buttonActive = new LivePredicateBool<>(active, activeBar -> activeBar == bar);
97
-					AspectBarSelectorButton button = new AspectBarSelectorButton(DStyleClass.EMPTY, bar.icon, buttonActive, e -> active.setValue(bar));
93
+					LiveBool buttonActive = new LivePredicateBool<>(aspectBar.active, activeBar -> activeBar == bar);
94
+					AspectBarSelectorButton button = new AspectBarSelectorButton(DStyleClass.EMPTY, bar.icon, buttonActive, e -> aspectBar.active.setValue(bar));
98 95
 					if (context != null)
99 96
 						button.setContext(path, context);
100 97
 					
101 98
 					return button;
102 99
 				});
100
+		selectorButtons.addListener(new SelectorButtonListListener());
103 101
 		
104
-		if (aspectBar.aspectToolbars.size() > 0)
105
-			active.setValue(aspectBar.aspectToolbars.get(0));
102
+		if (aspectBar.toolbars.size() > 0)
103
+			aspectBar.active.setValue(aspectBar.toolbars.get(0));
106 104
 	}
107 105
 	
108 106
 	@Override
@@ -118,7 +116,7 @@ public class AspectBarView extends BaseComponentGroup {
118 116
 		
119 117
 		if (bounds != null) {
120 118
 			layout();
121
-			active.setValue(active.getValue());
119
+			aspectBar.active.setValue(aspectBar.active.getValue());
122 120
 		}
123 121
 		
124 122
 		if (activeToolbarComponents != null)
@@ -155,8 +153,12 @@ public class AspectBarView extends BaseComponentGroup {
155 153
 		canvas.pushBounds(bounds);
156 154
 		canvas.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height, style.backgroundColor);
157 155
 		
158
-		for (DComponent button : selectorButtons)
156
+		for (DComponent button : selectorButtons) {
157
+			if (button.getBounds() == null)
158
+				continue;
159
+			
159 160
 			button.paint(canvas);
161
+		}
160 162
 		
161 163
 		canvas.shadowPath(
162 164
 				aspectBarShape,
@@ -167,15 +169,15 @@ public class AspectBarView extends BaseComponentGroup {
167 169
 				DTransform2D.IDENTITY,
168 170
 				style.foregroundColor);
169 171
 		
170
-		if (active.getValue() != null) {
172
+		if (aspectBar.active.getValue() != null) {
171 173
 			int y = bounds.y
172 174
 					+ style.aspectBarPaddingTop
173 175
 					+ (int)(activeToolbarTitleFontMetrics.getAscent() * 0.35f)
174 176
 					+ (bounds.height - style.aspectBarPaddingTop) / 2;
175 177
 			int x = aspectSelectorEndX + style.aspectSelectorToToolbarSpacing;
176
-			canvas.drawText(style.activeToolbarTitleFont, style.activeToolbarTitleColor, x, y, active.getValue().title);
178
+			canvas.drawText(style.activeToolbarTitleFont, style.activeToolbarTitleColor, x, y, aspectBar.active.getValue().title);
177 179
 			canvas.fillRectangle(
178
-					x + activeToolbarTitleFontMetrics.getWidth(active.getValue().title) + 8,
180
+					x + activeToolbarTitleFontMetrics.getWidth(aspectBar.active.getValue().title) + 8,
179 181
 					bounds.y + style.aspectBarPaddingTop + 8,
180 182
 					2,
181 183
 					bounds.height - style.aspectBarPaddingTop - 16,
@@ -236,6 +238,7 @@ public class AspectBarView extends BaseComponentGroup {
236 238
 		minimize.setBounds(new DIRectangle(x, bounds.y, minimizeSize.preferredWidth, minimizeSize.preferredHeight));
237 239
 		
238 240
 		calculateAspectBarShape();
241
+		context.repaint(bounds);
239 242
 	}
240 243
 	
241 244
 	private void layoutAspectSelectorButtons() {
@@ -262,7 +265,7 @@ public class AspectBarView extends BaseComponentGroup {
262 265
 		
263 266
 		int x = aspectSelectorEndX
264 267
 				+ style.aspectSelectorToToolbarSpacing
265
-				+ activeToolbarTitleFontMetrics.getWidth(active.getValue().title)
268
+				+ activeToolbarTitleFontMetrics.getWidth(aspectBar.active.getValue().title)
266 269
 				+ style.toolbarTitleToControlsSpacing;
267 270
 		
268 271
 		int y = style.aspectBarPaddingTop + style.controlPaddingTop;
@@ -363,24 +366,35 @@ public class AspectBarView extends BaseComponentGroup {
363 366
 		@Override
364 367
 		public void onInserted(int index, IDEAspectToolbar value) {
365 368
 			if (index == 0 && activeToolbarComponents == null)
366
-				active.setValue(value);
367
-			
368
-			layout();
369
+				aspectBar.active.setValue(value);
369 370
 		}
370 371
 
371 372
 		@Override
372 373
 		public void onChanged(int index, IDEAspectToolbar oldValue, IDEAspectToolbar newValue) {
373
-			if (oldValue == active.getValue())
374
-				active.setValue(newValue);
375
-			
376
-			layoutAspectSelectorButtons();
374
+			if (oldValue == aspectBar.active.getValue())
375
+				aspectBar.active.setValue(newValue);
377 376
 		}
378 377
 
379 378
 		@Override
380 379
 		public void onRemoved(int index, IDEAspectToolbar oldValue) {
381
-			if (oldValue == active.getValue())
382
-				active.setValue(aspectBar.aspectToolbars.size() == 0 ? null : aspectBar.aspectToolbars.get(0));
383
-			
380
+			if (oldValue == aspectBar.active.getValue())
381
+				aspectBar.active.setValue(aspectBar.toolbars.size() == 0 ? null : aspectBar.toolbars.get(0));
382
+		}
383
+	}
384
+	
385
+	private class SelectorButtonListListener implements LiveList.Listener<AspectBarSelectorButton> {
386
+		@Override
387
+		public void onInserted(int index, AspectBarSelectorButton value) {
388
+			layout();
389
+		}
390
+
391
+		@Override
392
+		public void onChanged(int index, AspectBarSelectorButton oldValue, AspectBarSelectorButton newValue) {
393
+			layoutAspectSelectorButtons();
394
+		}
395
+
396
+		@Override
397
+		public void onRemoved(int index, AspectBarSelectorButton oldValue) {
384 398
 			layout();
385 399
 		}
386 400
 	}

+ 1
- 1
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/aspectbar/WindowActionButton.java Visa fil

@@ -14,7 +14,7 @@ import org.openzen.drawablegui.DDimensionPreferences;
14 14
 import org.openzen.drawablegui.DMouseEvent;
15 15
 import org.openzen.drawablegui.DTransform2D;
16 16
 import org.openzen.drawablegui.DUIContext;
17
-import org.openzen.drawablegui.listeners.DIRectangle;
17
+import org.openzen.drawablegui.DIRectangle;
18 18
 import org.openzen.drawablegui.listeners.ListenerHandle;
19 19
 import org.openzen.drawablegui.live.LiveBool;
20 20
 import org.openzen.drawablegui.live.LiveObject;

+ 34
- 10
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java Visa fil

@@ -12,9 +12,10 @@ import org.openzen.drawablegui.DDimensionPreferences;
12 12
 import org.openzen.drawablegui.DFont;
13 13
 import org.openzen.drawablegui.DFontFamily;
14 14
 import org.openzen.drawablegui.DFontMetrics;
15
-import org.openzen.drawablegui.listeners.DIRectangle;
15
+import org.openzen.drawablegui.DIRectangle;
16 16
 import org.openzen.drawablegui.DKeyEvent;
17 17
 import org.openzen.drawablegui.DMouseEvent;
18
+import org.openzen.drawablegui.DTimerHandle;
18 19
 import org.openzen.drawablegui.DTransform2D;
19 20
 import org.openzen.drawablegui.listeners.ListenerHandle;
20 21
 import org.openzen.drawablegui.live.LiveObject;
@@ -22,7 +23,6 @@ import org.openzen.drawablegui.live.SimpleLiveObject;
22 23
 import org.openzen.zenscript.ide.host.IDESourceFile;
23 24
 import org.openzen.zenscript.ide.ui.IDEAspectToolbar;
24 25
 import org.openzen.zenscript.ide.ui.IDEWindow;
25
-import org.openzen.zenscript.ide.ui.icons.CodeIcon;
26 26
 import org.openzen.zenscript.lexer.ReaderCharReader;
27 27
 import org.openzen.zenscript.lexer.TokenParser;
28 28
 import org.openzen.zenscript.lexer.ZSToken;
@@ -33,6 +33,8 @@ import org.openzen.drawablegui.live.SimpleLiveBool;
33 33
 import org.openzen.drawablegui.style.DStyleClass;
34 34
 import org.openzen.drawablegui.style.DStylePath;
35 35
 import org.openzen.zenscript.ide.ui.icons.SaveIcon;
36
+import org.openzen.zenscript.ide.ui.icons.ShadedCodeIcon;
37
+import org.openzen.zenscript.ide.ui.icons.ShadedSaveIcon;
36 38
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
37 39
 
38 40
 /**
@@ -52,6 +54,7 @@ public class SourceEditor implements DComponent {
52 54
 	private DIRectangle bounds;
53 55
 	private DUIContext context;
54 56
 	private SourceEditorStyle style;
57
+	private DTimerHandle blinkTimer;
55 58
 	
56 59
 	private DFontMetrics fontMetrics;
57 60
 	private int textLineHeight;
@@ -69,7 +72,7 @@ public class SourceEditor implements DComponent {
69 72
 	private boolean dragging = false;
70 73
 	
71 74
 	private final IDEWindow window;
72
-	private final IDEAspectToolbar editToolbar = new IDEAspectToolbar(0, CodeIcon.GREY, "Edit", "Source code editor");
75
+	private final IDEAspectToolbar editToolbar = new IDEAspectToolbar(0, ShadedCodeIcon.BLUE, "Edit", "Source code editor");
73 76
 	
74 77
 	public SourceEditor(DStyleClass styleClass, IDEWindow window, IDESourceFile sourceFile) {
75 78
 		this.styleClass = styleClass;
@@ -79,8 +82,7 @@ public class SourceEditor implements DComponent {
79 82
 		tokens = new TokenModel(sourceFile.getName(), tab.length());
80 83
 		tokenListener = tokens.addListener(new TokenListener());
81 84
 		
82
-		editToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, SaveIcon.BLACK, SaveIcon.GREY, unchanged, e -> save()));
83
-		window.aspectBar.addToolbar(editToolbar);
85
+		editToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, ShadedSaveIcon.PURPLE, SaveIcon.GREY, unchanged, e -> save()));
84 86
 		
85 87
 		try {
86 88
 			TokenParser<ZSToken, ZSTokenType> parser = ZSTokenParser.createRaw(
@@ -93,9 +95,22 @@ public class SourceEditor implements DComponent {
93 95
 		}
94 96
 	}
95 97
 	
98
+	@Override
99
+	public void onMounted() {
100
+		window.aspectBar.toolbars.add(editToolbar);
101
+		window.aspectBar.active.setValue(editToolbar);
102
+	}
103
+	
104
+	@Override
105
+	public void onUnmounted() {
106
+		window.aspectBar.toolbars.remove(editToolbar);
107
+	}
108
+	
96 109
 	@Override
97 110
 	public void close() {
98
-		window.aspectBar.removeToolbar(editToolbar);
111
+		if (blinkTimer != null)
112
+			blinkTimer.close();
113
+		
99 114
 		tokenListener.close();
100 115
 	}
101 116
 
@@ -110,7 +125,10 @@ public class SourceEditor implements DComponent {
110 125
 		selectionLineHeight = textLineHeight + style.selectionPaddingTop + style.selectionPaddingBottom;
111 126
 		
112 127
 		dimensionPreferences.setValue(new DDimensionPreferences(0, fullLineHeight * tokens.getLineCount()));
113
-		context.setTimer(300, this::blink);
128
+		
129
+		if (blinkTimer != null)
130
+			blinkTimer.close();
131
+		blinkTimer = context.setTimer(300, this::blink);
114 132
 	}
115 133
 
116 134
 	@Override
@@ -217,9 +235,12 @@ public class SourceEditor implements DComponent {
217 235
 		if (e.isDoubleClick()) {
218 236
 			// select entire word
219 237
 			TokenModel.Position tokenPosition = tokens.getPosition(position.line, position.offset);
220
-			setCursor(
221
-					new SourcePosition(tokens, position.line, position.offset - tokenPosition.offset),
222
-					new SourcePosition(tokens, position.line, position.offset - tokenPosition.offset + tokens.getTokenAt(tokenPosition).content.length()));
238
+			ZSToken token = tokens.getTokenAt(tokenPosition);
239
+			if (token != null) {
240
+				setCursor(
241
+						new SourcePosition(tokens, position.line, position.offset - tokenPosition.offset),
242
+						new SourcePosition(tokens, position.line, position.offset - tokenPosition.offset + token.content.length()));
243
+			}
223 244
 		} else if (e.isTripleClick()) {
224 245
 			setCursor(
225 246
 					new SourcePosition(tokens, position.line, 0),
@@ -400,6 +421,9 @@ public class SourceEditor implements DComponent {
400 421
 	}
401 422
 	
402 423
 	private void delete() {
424
+		if (deleteSelection())
425
+			return;
426
+		
403 427
 		TokenLine line = tokens.getLine(cursorEnd.line);
404 428
 		if (cursorEnd.offset == line.length()) {
405 429
 			// merge 2 lines

+ 26
- 3
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenLine.java Visa fil

@@ -56,8 +56,7 @@ public final class TokenLine {
56 56
 	}
57 57
 
58 58
 	public void add(ZSToken token) {
59
-		tokens.add(token);
60
-		length += token.content.length();
59
+		insert(tokens.size(), token);
61 60
 	}
62 61
 
63 62
 	public void addAll(Iterable<ZSToken> tokens) {
@@ -66,9 +65,33 @@ public final class TokenLine {
66 65
 		}
67 66
 	}
68 67
 
69
-	public void insert(int index, ZSToken token) {
68
+	public int insert(int index, ZSToken token) {
69
+		if (token.type != ZSTokenType.T_WHITESPACE_TAB && token.content.indexOf('\t') >= 0) {
70
+			int start = 0;
71
+			int tokens = 0;
72
+			for (int i = 0; i < token.content.length(); i++) {
73
+				if (token.content.charAt(i) == '\t') {
74
+					if (i > start) {
75
+						insert(index++, new ZSToken(token.type, token.content.substring(start, i)));
76
+						tokens++;
77
+					}
78
+					insert(index++, ZSTokenType.T_WHITESPACE_TAB.flyweight);
79
+					tokens++;
80
+					start = i + 1;
81
+				}
82
+			}
83
+			
84
+			if (start < token.content.length()) {
85
+				insert(index++, new ZSToken(token.type, token.content.substring(start)));
86
+				tokens++;
87
+			}
88
+			
89
+			return tokens;
90
+		}
91
+		
70 92
 		tokens.add(index, token);
71 93
 		length += token.content.length();
94
+		return 1;
72 95
 	}
73 96
 
74 97
 	public void replace(int index, ZSToken token) {

+ 1
- 2
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenModel.java Visa fil

@@ -273,8 +273,7 @@ public class TokenModel {
273 273
 					if (!parts[0].isEmpty())
274 274
 						currentLine.add(new ZSToken(token.type, parts[0]));
275 275
 					if (!parts[parts.length - 1].isEmpty()) {
276
-						newLine.insert(0, new ZSToken(token.type, parts[parts.length - 1]));
277
-						tokenIndex++;
276
+						tokenIndex += newLine.insert(0, new ZSToken(token.type, parts[parts.length - 1]));
278 277
 					}
279 278
 					
280 279
 					for (int i = 1; i < parts.length - 1; i++) {

+ 8
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/project/ProjectTreeNode.java Visa fil

@@ -6,6 +6,7 @@
6 6
 package org.openzen.zenscript.ide.ui.view.project;
7 7
 
8 8
 import org.openzen.drawablegui.DColorableIcon;
9
+import org.openzen.drawablegui.DMouseEvent;
9 10
 import org.openzen.drawablegui.live.LiveList;
10 11
 import org.openzen.drawablegui.live.LiveMappedList;
11 12
 import org.openzen.zenscript.ide.host.DevelopmentHost;
@@ -17,10 +18,12 @@ import org.openzen.zenscript.ide.ui.icons.ProjectIcon;
17 18
  * @author Hoofdgebruiker
18 19
  */
19 20
 public class ProjectTreeNode extends ProjectOverviewNode {
21
+	private final IDEWindow window;
20 22
 	private final DevelopmentHost host;
21 23
 	private final LiveList<ProjectOverviewNode> modules;
22 24
 	
23 25
 	public ProjectTreeNode(IDEWindow window, DevelopmentHost host) {
26
+		this.window = window;
24 27
 		this.host = host;
25 28
 		
26 29
 		modules = new LiveMappedList<>(host.getModules(), module -> new ModuleTreeNode(window, module));
@@ -50,4 +53,9 @@ public class ProjectTreeNode extends ProjectOverviewNode {
50 53
 	public boolean isLeaf() {
51 54
 		return false;
52 55
 	}
56
+	
57
+	@Override
58
+	public void onMouseClick(DMouseEvent e) {
59
+		window.aspectBar.active.setValue(window.projectToolbar);
60
+	}
53 61
 }

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java Visa fil

@@ -11,7 +11,7 @@ package org.openzen.zenscript.lexer;
11 11
  */
12 12
 public enum ZSTokenType implements TokenType {
13 13
 	T_COMMENT_SCRIPT("#[^\n]*[\n\\e]", true),
14
-	T_COMMENT_SINGLELINE("//[^\n]*[\n\\e]", true),
14
+	T_COMMENT_SINGLELINE("//[^\n]*", true),
15 15
 	T_COMMENT_MULTILINE("/\\*([^\\*]|(\\*+([^\\*/])))*\\*+/", true, true),
16 16
 	T_WHITESPACE_SPACE(true, " ", " "),
17 17
 	T_WHITESPACE_TAB(true, "\t", "\t"),

Loading…
Avbryt
Spara