Browse Source

Added tabs + support for multiple open source files

Stan Hebben 6 years ago
parent
commit
637b2399d5
46 changed files with 1115 additions and 150 deletions
  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 View File

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

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

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

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

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

DrawableGui/src/main/java/org/openzen/drawablegui/listeners/DIRectangle.java → DrawableGui/src/main/java/org/openzen/drawablegui/DIRectangle.java View File

3
  * To change this template file, choose Tools | Templates
3
  * To change this template file, choose Tools | Templates
4
  * and open the template in the editor.
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
  * @author Hoofdgebruiker
10
  * @author Hoofdgebruiker
11
  */
11
  */
12
 public class DIRectangle {
12
 public class DIRectangle {
13
+	public static final DIRectangle EMPTY = new DIRectangle(0, 0, 0, 0);
14
+	
13
 	public final int x;
15
 	public final int x;
14
 	public final int y;
16
 	public final int y;
15
 	public final int width;
17
 	public final int width;

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

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

+ 6
- 4
DrawableGui/src/main/java/org/openzen/drawablegui/DSideLayout.java View File

5
  */
5
  */
6
 package org.openzen.drawablegui;
6
 package org.openzen.drawablegui;
7
 
7
 
8
-import org.openzen.drawablegui.listeners.DIRectangle;
9
 import java.io.Closeable;
8
 import java.io.Closeable;
10
 import java.util.ArrayList;
9
 import java.util.ArrayList;
11
 import java.util.List;
10
 import java.util.List;
49
 			this.main.close();
48
 			this.main.close();
50
 		
49
 		
51
 		this.main = component;
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
 	@Override
59
 	@Override

+ 16
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/DTransform2D.java View File

51
 	public float getY(float x, float y) {
51
 	public float getY(float x, float y) {
52
 		return x * yx + y * yy + dy;
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 View File

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

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

6
 package org.openzen.drawablegui.border;
6
 package org.openzen.drawablegui.border;
7
 
7
 
8
 import org.openzen.drawablegui.DCanvas;
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 View File

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

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

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

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

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

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

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

+ 11
- 1
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java View File

11
 import org.openzen.drawablegui.DDimensionPreferences;
11
 import org.openzen.drawablegui.DDimensionPreferences;
12
 import org.openzen.drawablegui.DFont;
12
 import org.openzen.drawablegui.DFont;
13
 import org.openzen.drawablegui.DFontMetrics;
13
 import org.openzen.drawablegui.DFontMetrics;
14
-import org.openzen.drawablegui.listeners.DIRectangle;
14
+import org.openzen.drawablegui.DIRectangle;
15
 import org.openzen.drawablegui.DMouseEvent;
15
 import org.openzen.drawablegui.DMouseEvent;
16
 import org.openzen.drawablegui.DTimerHandle;
16
 import org.openzen.drawablegui.DTimerHandle;
17
 import org.openzen.drawablegui.listeners.ListenerHandle;
17
 import org.openzen.drawablegui.listeners.ListenerHandle;
68
 			contentsHeight.setValue(newPreferences.preferredHeight);
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
 	@Override
82
 	@Override
73
 	public void setContext(DStylePath parent, DUIContext context) {
83
 	public void setContext(DStylePath parent, DUIContext context) {

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

21
 import org.openzen.drawablegui.DFont;
21
 import org.openzen.drawablegui.DFont;
22
 import org.openzen.drawablegui.DFontFamily;
22
 import org.openzen.drawablegui.DFontFamily;
23
 import org.openzen.drawablegui.DTransform2D;
23
 import org.openzen.drawablegui.DTransform2D;
24
-import org.openzen.drawablegui.listeners.DIRectangle;
24
+import org.openzen.drawablegui.DIRectangle;
25
 import org.openzen.drawablegui.DPath;
25
 import org.openzen.drawablegui.DPath;
26
 import org.openzen.drawablegui.DPathBoundsCalculator;
26
 import org.openzen.drawablegui.DPathBoundsCalculator;
27
 import org.openzen.drawablegui.DUIContext;
27
 import org.openzen.drawablegui.DUIContext;
132
 		
132
 		
133
 		GeneralPath jPath = context.getPath(path);
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
 		Graphics2D imageG = (Graphics2D) image.getGraphics();
136
 		Graphics2D imageG = (Graphics2D) image.getGraphics();
137
 		
137
 		
138
 		imageG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
138
 		imageG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

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

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

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

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

+ 2
- 2
DrawableGuiIconConverter/src/main/java/org/openzen/drawablegui/iconconverter/Main.java View File

21
  */
21
  */
22
 public class Main {
22
 public class Main {
23
 	public static void main(String[] args) throws Exception {
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
 		//String filename = "baseline-dashboard-24px.svg";
25
 		//String filename = "baseline-dashboard-24px.svg";
26
-		String className = "ColorableCloseIcon";
26
+		String className = "BuildIcon";
27
 		File file = new File(filename);
27
 		File file = new File(filename);
28
 		if (!file.exists()) {
28
 		if (!file.exists()) {
29
 			System.out.println("No such file: " + filename);
29
 			System.out.println("No such file: " + filename);

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

5
  */
5
  */
6
 package org.openzen.zenscript.ide.ui;
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
 import org.openzen.drawablegui.live.LiveArrayList;
8
 import org.openzen.drawablegui.live.LiveArrayList;
12
 import org.openzen.drawablegui.live.LiveList;
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
  * @author Hoofdgebruiker
15
  * @author Hoofdgebruiker
17
  */
16
  */
18
 public class IDEAspectBar {
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 View File

5
  */
5
  */
6
 package org.openzen.zenscript.ide.ui;
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
 import org.openzen.zenscript.ide.host.IDESourceFile;
10
 import org.openzen.zenscript.ide.host.IDESourceFile;
11
 
11
 
12
 /**
12
 /**
14
  * @author Hoofdgebruiker
14
  * @author Hoofdgebruiker
15
  */
15
  */
16
 public class IDEDockWindow {
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 View File

9
 import org.openzen.drawablegui.style.DStyleClass;
9
 import org.openzen.drawablegui.style.DStyleClass;
10
 import org.openzen.zenscript.ide.host.IDESourceFile;
10
 import org.openzen.zenscript.ide.host.IDESourceFile;
11
 import org.openzen.zenscript.ide.ui.icons.AddBoxIcon;
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
 import org.openzen.zenscript.ide.ui.icons.ProjectIcon;
14
 import org.openzen.zenscript.ide.ui.icons.ProjectIcon;
13
 import org.openzen.zenscript.ide.ui.icons.SettingsIcon;
15
 import org.openzen.zenscript.ide.ui.icons.SettingsIcon;
16
+import org.openzen.zenscript.ide.ui.icons.ShadedProjectIcon;
14
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
17
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
15
 
18
 
16
 /**
19
 /**
22
 	public final IDEDockWindow dockWindow;
25
 	public final IDEDockWindow dockWindow;
23
 	public final IDEStatusBar statusBar;
26
 	public final IDEStatusBar statusBar;
24
 	
27
 	
28
+	public IDEAspectToolbar projectToolbar;
29
+	
25
 	public IDEWindow() {
30
 	public IDEWindow() {
26
 		aspectBar = new IDEAspectBar();
31
 		aspectBar = new IDEAspectBar();
27
 		dockWindow = new IDEDockWindow();
32
 		dockWindow = new IDEDockWindow();
37
 	}
42
 	}
38
 	
43
 	
39
 	public void open(IDESourceFile sourceFile) {
44
 	public void open(IDESourceFile sourceFile) {
40
-		dockWindow.currentSourceFile.setValue(sourceFile);
45
+		dockWindow.open(sourceFile);
41
 	}
46
 	}
42
 	
47
 	
43
 	private void init() {
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 View File

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

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

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

13
 public class SettingsIcon implements DColorableIcon {
13
 public class SettingsIcon implements DColorableIcon {
14
 	public static final SettingsIcon INSTANCE = new SettingsIcon();
14
 	public static final SettingsIcon INSTANCE = new SettingsIcon();
15
 	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
15
 	public static final ColoredIcon BLACK = new ColoredIcon(INSTANCE, 0xFF000000);
16
+	public static final ColoredIcon PURPLE = new ColoredIcon(INSTANCE, 0xFF5758BB);
16
 	
17
 	
17
 	private SettingsIcon() {}
18
 	private SettingsIcon() {}
18
 	
19
 	
67
 	
68
 	
68
 	@Override
69
 	@Override
69
 	public void draw(DCanvas canvas, DTransform2D transform, int color) {
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
 		canvas.fillPath(PATH, transform, color);
72
 		canvas.fillPath(PATH, transform, color);
72
 	}
73
 	}
73
 
74
 

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

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

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

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

8
 import org.openzen.drawablegui.DCanvas;
8
 import org.openzen.drawablegui.DCanvas;
9
 import org.openzen.drawablegui.DComponent;
9
 import org.openzen.drawablegui.DComponent;
10
 import org.openzen.drawablegui.DDimensionPreferences;
10
 import org.openzen.drawablegui.DDimensionPreferences;
11
-import org.openzen.drawablegui.listeners.DIRectangle;
11
+import org.openzen.drawablegui.DIRectangle;
12
 import org.openzen.drawablegui.live.LiveObject;
12
 import org.openzen.drawablegui.live.LiveObject;
13
 import org.openzen.drawablegui.live.SimpleLiveObject;
13
 import org.openzen.drawablegui.live.SimpleLiveObject;
14
 import org.openzen.drawablegui.DUIContext;
14
 import org.openzen.drawablegui.DUIContext;

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

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.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 View File

5
  */
5
  */
6
 package org.openzen.zenscript.ide.ui.view;
6
 package org.openzen.zenscript.ide.ui.view;
7
 
7
 
8
+import org.openzen.drawablegui.DComponent;
8
 import org.openzen.drawablegui.DDimensionPreferences;
9
 import org.openzen.drawablegui.DDimensionPreferences;
10
+import org.openzen.drawablegui.DDrawable;
9
 import org.openzen.drawablegui.DEmptyView;
11
 import org.openzen.drawablegui.DEmptyView;
10
 import org.openzen.drawablegui.scroll.DScrollPane;
12
 import org.openzen.drawablegui.scroll.DScrollPane;
11
 import org.openzen.drawablegui.DSideLayout;
13
 import org.openzen.drawablegui.DSideLayout;
14
+import org.openzen.drawablegui.live.LiveList;
12
 import org.openzen.drawablegui.style.DStyleClass;
15
 import org.openzen.drawablegui.style.DStyleClass;
13
 import org.openzen.drawablegui.tree.DTreeView;
16
 import org.openzen.drawablegui.tree.DTreeView;
14
 import org.openzen.drawablegui.tree.DTreeViewStyle;
17
 import org.openzen.drawablegui.tree.DTreeViewStyle;
15
 import org.openzen.zenscript.ide.host.DevelopmentHost;
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
 import org.openzen.zenscript.ide.ui.IDEWindow;
21
 import org.openzen.zenscript.ide.ui.IDEWindow;
17
 import org.openzen.zenscript.ide.ui.view.aspectbar.AspectBarView;
22
 import org.openzen.zenscript.ide.ui.view.aspectbar.AspectBarView;
18
 import org.openzen.zenscript.ide.ui.view.editor.SourceEditor;
23
 import org.openzen.zenscript.ide.ui.view.editor.SourceEditor;
23
  * @author Hoofdgebruiker
28
  * @author Hoofdgebruiker
24
  */
29
  */
25
 public final class WindowView extends DSideLayout {
30
 public final class WindowView extends DSideLayout {
31
+	private final IDEWindow window;
32
+	private final TabbedView tabs;
33
+	
26
 	public WindowView(IDEWindow window, DevelopmentHost host) {
34
 	public WindowView(IDEWindow window, DevelopmentHost host) {
27
 		super(DStyleClass.EMPTY, DEmptyView.INSTANCE);
35
 		super(DStyleClass.EMPTY, DEmptyView.INSTANCE);
36
+		this.window = window;
28
 		
37
 		
29
 		DTreeView projectView = new DTreeView(DTreeViewStyle.DEFAULT, new RootTreeNode(window, host), false);
38
 		DTreeView projectView = new DTreeView(DTreeViewStyle.DEFAULT, new RootTreeNode(window, host), false);
30
 		projectView.getDimensionPreferences().setValue(new DDimensionPreferences(500, 500));
39
 		projectView.getDimensionPreferences().setValue(new DDimensionPreferences(500, 500));
40
+		setMain(tabs = new TabbedView(DStyleClass.EMPTY));
31
 		add(Side.LEFT, new DScrollPane(DStyleClass.forId("projectView"), projectView));
41
 		add(Side.LEFT, new DScrollPane(DStyleClass.forId("projectView"), projectView));
32
 		add(Side.BOTTOM, new StatusBarView());
42
 		add(Side.BOTTOM, new StatusBarView());
33
 		add(Side.TOP, new AspectBarView(DStyleClass.EMPTY, window.aspectBar));
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 View File

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

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

16
 import org.openzen.drawablegui.DFontMetrics;
16
 import org.openzen.drawablegui.DFontMetrics;
17
 import org.openzen.drawablegui.DPath;
17
 import org.openzen.drawablegui.DPath;
18
 import org.openzen.drawablegui.DTransform2D;
18
 import org.openzen.drawablegui.DTransform2D;
19
-import org.openzen.drawablegui.listeners.DIRectangle;
19
+import org.openzen.drawablegui.DIRectangle;
20
 import org.openzen.drawablegui.live.LiveObject;
20
 import org.openzen.drawablegui.live.LiveObject;
21
 import org.openzen.drawablegui.live.SimpleLiveObject;
21
 import org.openzen.drawablegui.live.SimpleLiveObject;
22
 import org.openzen.zenscript.ide.ui.IDEAspectBar;
22
 import org.openzen.zenscript.ide.ui.IDEAspectBar;
28
 import org.openzen.drawablegui.live.LiveList;
28
 import org.openzen.drawablegui.live.LiveList;
29
 import org.openzen.drawablegui.live.LiveMappedList;
29
 import org.openzen.drawablegui.live.LiveMappedList;
30
 import org.openzen.drawablegui.live.LivePredicateBool;
30
 import org.openzen.drawablegui.live.LivePredicateBool;
31
-import org.openzen.drawablegui.live.SimpleLiveBool;
32
 import org.openzen.drawablegui.style.DStyleClass;
31
 import org.openzen.drawablegui.style.DStyleClass;
33
 import org.openzen.drawablegui.style.DStylePath;
32
 import org.openzen.drawablegui.style.DStylePath;
34
 import org.openzen.zenscript.ide.ui.IDEAspectBarControl;
33
 import org.openzen.zenscript.ide.ui.IDEAspectBarControl;
35
-import org.openzen.zenscript.ide.ui.icons.CloseIcon;
36
 import org.openzen.zenscript.ide.ui.icons.ScalableCloseIcon;
34
 import org.openzen.zenscript.ide.ui.icons.ScalableCloseIcon;
37
 import org.openzen.zenscript.ide.ui.icons.ScalableMaximizeIcon;
35
 import org.openzen.zenscript.ide.ui.icons.ScalableMaximizeIcon;
38
 import org.openzen.zenscript.ide.ui.icons.ScalableMinimizeIcon;
36
 import org.openzen.zenscript.ide.ui.icons.ScalableMinimizeIcon;
55
 	private boolean showWindowControls;
53
 	private boolean showWindowControls;
56
 	
54
 	
57
 	private final LiveMappedList<IDEAspectToolbar, AspectBarSelectorButton> selectorButtons;
55
 	private final LiveMappedList<IDEAspectToolbar, AspectBarSelectorButton> selectorButtons;
58
-	public final LiveObject<IDEAspectToolbar> active = new SimpleLiveObject<>(null);
59
 	private LiveMappedList<IDEAspectBarControl, DComponent> activeToolbarComponents;
56
 	private LiveMappedList<IDEAspectBarControl, DComponent> activeToolbarComponents;
60
 	
57
 	
61
 	private final ListenerHandle<LiveList.Listener<IDEAspectToolbar>> listener;
58
 	private final ListenerHandle<LiveList.Listener<IDEAspectToolbar>> listener;
75
 		this.styleClass = styleClass;
72
 		this.styleClass = styleClass;
76
 		this.aspectBar = aspectBar;
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
 		minimize = new WindowActionButton(scale -> new ScalableMinimizeIcon(scale), e -> context.getWindow().minimize());
78
 		minimize = new WindowActionButton(scale -> new ScalableMinimizeIcon(scale), e -> context.getWindow().minimize());
82
 		minimizeRelayout = minimize.getDimensionPreferences().addListener((a, b) -> layout());
79
 		minimizeRelayout = minimize.getDimensionPreferences().addListener((a, b) -> layout());
91
 		closeRelayout = close.getDimensionPreferences().addListener((a, b) -> layout());
88
 		closeRelayout = close.getDimensionPreferences().addListener((a, b) -> layout());
92
 		
89
 		
93
 		selectorButtons = new LiveMappedList<>(
90
 		selectorButtons = new LiveMappedList<>(
94
-				aspectBar.aspectToolbars,
91
+				aspectBar.toolbars,
95
 				bar -> {
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
 					if (context != null)
95
 					if (context != null)
99
 						button.setContext(path, context);
96
 						button.setContext(path, context);
100
 					
97
 					
101
 					return button;
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
 	@Override
106
 	@Override
118
 		
116
 		
119
 		if (bounds != null) {
117
 		if (bounds != null) {
120
 			layout();
118
 			layout();
121
-			active.setValue(active.getValue());
119
+			aspectBar.active.setValue(aspectBar.active.getValue());
122
 		}
120
 		}
123
 		
121
 		
124
 		if (activeToolbarComponents != null)
122
 		if (activeToolbarComponents != null)
155
 		canvas.pushBounds(bounds);
153
 		canvas.pushBounds(bounds);
156
 		canvas.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height, style.backgroundColor);
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
 			button.paint(canvas);
160
 			button.paint(canvas);
161
+		}
160
 		
162
 		
161
 		canvas.shadowPath(
163
 		canvas.shadowPath(
162
 				aspectBarShape,
164
 				aspectBarShape,
167
 				DTransform2D.IDENTITY,
169
 				DTransform2D.IDENTITY,
168
 				style.foregroundColor);
170
 				style.foregroundColor);
169
 		
171
 		
170
-		if (active.getValue() != null) {
172
+		if (aspectBar.active.getValue() != null) {
171
 			int y = bounds.y
173
 			int y = bounds.y
172
 					+ style.aspectBarPaddingTop
174
 					+ style.aspectBarPaddingTop
173
 					+ (int)(activeToolbarTitleFontMetrics.getAscent() * 0.35f)
175
 					+ (int)(activeToolbarTitleFontMetrics.getAscent() * 0.35f)
174
 					+ (bounds.height - style.aspectBarPaddingTop) / 2;
176
 					+ (bounds.height - style.aspectBarPaddingTop) / 2;
175
 			int x = aspectSelectorEndX + style.aspectSelectorToToolbarSpacing;
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
 			canvas.fillRectangle(
179
 			canvas.fillRectangle(
178
-					x + activeToolbarTitleFontMetrics.getWidth(active.getValue().title) + 8,
180
+					x + activeToolbarTitleFontMetrics.getWidth(aspectBar.active.getValue().title) + 8,
179
 					bounds.y + style.aspectBarPaddingTop + 8,
181
 					bounds.y + style.aspectBarPaddingTop + 8,
180
 					2,
182
 					2,
181
 					bounds.height - style.aspectBarPaddingTop - 16,
183
 					bounds.height - style.aspectBarPaddingTop - 16,
236
 		minimize.setBounds(new DIRectangle(x, bounds.y, minimizeSize.preferredWidth, minimizeSize.preferredHeight));
238
 		minimize.setBounds(new DIRectangle(x, bounds.y, minimizeSize.preferredWidth, minimizeSize.preferredHeight));
237
 		
239
 		
238
 		calculateAspectBarShape();
240
 		calculateAspectBarShape();
241
+		context.repaint(bounds);
239
 	}
242
 	}
240
 	
243
 	
241
 	private void layoutAspectSelectorButtons() {
244
 	private void layoutAspectSelectorButtons() {
262
 		
265
 		
263
 		int x = aspectSelectorEndX
266
 		int x = aspectSelectorEndX
264
 				+ style.aspectSelectorToToolbarSpacing
267
 				+ style.aspectSelectorToToolbarSpacing
265
-				+ activeToolbarTitleFontMetrics.getWidth(active.getValue().title)
268
+				+ activeToolbarTitleFontMetrics.getWidth(aspectBar.active.getValue().title)
266
 				+ style.toolbarTitleToControlsSpacing;
269
 				+ style.toolbarTitleToControlsSpacing;
267
 		
270
 		
268
 		int y = style.aspectBarPaddingTop + style.controlPaddingTop;
271
 		int y = style.aspectBarPaddingTop + style.controlPaddingTop;
363
 		@Override
366
 		@Override
364
 		public void onInserted(int index, IDEAspectToolbar value) {
367
 		public void onInserted(int index, IDEAspectToolbar value) {
365
 			if (index == 0 && activeToolbarComponents == null)
368
 			if (index == 0 && activeToolbarComponents == null)
366
-				active.setValue(value);
367
-			
368
-			layout();
369
+				aspectBar.active.setValue(value);
369
 		}
370
 		}
370
 
371
 
371
 		@Override
372
 		@Override
372
 		public void onChanged(int index, IDEAspectToolbar oldValue, IDEAspectToolbar newValue) {
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
 		@Override
378
 		@Override
380
 		public void onRemoved(int index, IDEAspectToolbar oldValue) {
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
 			layout();
398
 			layout();
385
 		}
399
 		}
386
 	}
400
 	}

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

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

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

12
 import org.openzen.drawablegui.DFont;
12
 import org.openzen.drawablegui.DFont;
13
 import org.openzen.drawablegui.DFontFamily;
13
 import org.openzen.drawablegui.DFontFamily;
14
 import org.openzen.drawablegui.DFontMetrics;
14
 import org.openzen.drawablegui.DFontMetrics;
15
-import org.openzen.drawablegui.listeners.DIRectangle;
15
+import org.openzen.drawablegui.DIRectangle;
16
 import org.openzen.drawablegui.DKeyEvent;
16
 import org.openzen.drawablegui.DKeyEvent;
17
 import org.openzen.drawablegui.DMouseEvent;
17
 import org.openzen.drawablegui.DMouseEvent;
18
+import org.openzen.drawablegui.DTimerHandle;
18
 import org.openzen.drawablegui.DTransform2D;
19
 import org.openzen.drawablegui.DTransform2D;
19
 import org.openzen.drawablegui.listeners.ListenerHandle;
20
 import org.openzen.drawablegui.listeners.ListenerHandle;
20
 import org.openzen.drawablegui.live.LiveObject;
21
 import org.openzen.drawablegui.live.LiveObject;
22
 import org.openzen.zenscript.ide.host.IDESourceFile;
23
 import org.openzen.zenscript.ide.host.IDESourceFile;
23
 import org.openzen.zenscript.ide.ui.IDEAspectToolbar;
24
 import org.openzen.zenscript.ide.ui.IDEAspectToolbar;
24
 import org.openzen.zenscript.ide.ui.IDEWindow;
25
 import org.openzen.zenscript.ide.ui.IDEWindow;
25
-import org.openzen.zenscript.ide.ui.icons.CodeIcon;
26
 import org.openzen.zenscript.lexer.ReaderCharReader;
26
 import org.openzen.zenscript.lexer.ReaderCharReader;
27
 import org.openzen.zenscript.lexer.TokenParser;
27
 import org.openzen.zenscript.lexer.TokenParser;
28
 import org.openzen.zenscript.lexer.ZSToken;
28
 import org.openzen.zenscript.lexer.ZSToken;
33
 import org.openzen.drawablegui.style.DStyleClass;
33
 import org.openzen.drawablegui.style.DStyleClass;
34
 import org.openzen.drawablegui.style.DStylePath;
34
 import org.openzen.drawablegui.style.DStylePath;
35
 import org.openzen.zenscript.ide.ui.icons.SaveIcon;
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
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
38
 import org.openzen.zenscript.ide.ui.view.IconButtonControl;
37
 
39
 
38
 /**
40
 /**
52
 	private DIRectangle bounds;
54
 	private DIRectangle bounds;
53
 	private DUIContext context;
55
 	private DUIContext context;
54
 	private SourceEditorStyle style;
56
 	private SourceEditorStyle style;
57
+	private DTimerHandle blinkTimer;
55
 	
58
 	
56
 	private DFontMetrics fontMetrics;
59
 	private DFontMetrics fontMetrics;
57
 	private int textLineHeight;
60
 	private int textLineHeight;
69
 	private boolean dragging = false;
72
 	private boolean dragging = false;
70
 	
73
 	
71
 	private final IDEWindow window;
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
 	public SourceEditor(DStyleClass styleClass, IDEWindow window, IDESourceFile sourceFile) {
77
 	public SourceEditor(DStyleClass styleClass, IDEWindow window, IDESourceFile sourceFile) {
75
 		this.styleClass = styleClass;
78
 		this.styleClass = styleClass;
79
 		tokens = new TokenModel(sourceFile.getName(), tab.length());
82
 		tokens = new TokenModel(sourceFile.getName(), tab.length());
80
 		tokenListener = tokens.addListener(new TokenListener());
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
 		try {
87
 		try {
86
 			TokenParser<ZSToken, ZSTokenType> parser = ZSTokenParser.createRaw(
88
 			TokenParser<ZSToken, ZSTokenType> parser = ZSTokenParser.createRaw(
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
 	@Override
109
 	@Override
97
 	public void close() {
110
 	public void close() {
98
-		window.aspectBar.removeToolbar(editToolbar);
111
+		if (blinkTimer != null)
112
+			blinkTimer.close();
113
+		
99
 		tokenListener.close();
114
 		tokenListener.close();
100
 	}
115
 	}
101
 
116
 
110
 		selectionLineHeight = textLineHeight + style.selectionPaddingTop + style.selectionPaddingBottom;
125
 		selectionLineHeight = textLineHeight + style.selectionPaddingTop + style.selectionPaddingBottom;
111
 		
126
 		
112
 		dimensionPreferences.setValue(new DDimensionPreferences(0, fullLineHeight * tokens.getLineCount()));
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
 	@Override
134
 	@Override
217
 		if (e.isDoubleClick()) {
235
 		if (e.isDoubleClick()) {
218
 			// select entire word
236
 			// select entire word
219
 			TokenModel.Position tokenPosition = tokens.getPosition(position.line, position.offset);
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
 		} else if (e.isTripleClick()) {
244
 		} else if (e.isTripleClick()) {
224
 			setCursor(
245
 			setCursor(
225
 					new SourcePosition(tokens, position.line, 0),
246
 					new SourcePosition(tokens, position.line, 0),
400
 	}
421
 	}
401
 	
422
 	
402
 	private void delete() {
423
 	private void delete() {
424
+		if (deleteSelection())
425
+			return;
426
+		
403
 		TokenLine line = tokens.getLine(cursorEnd.line);
427
 		TokenLine line = tokens.getLine(cursorEnd.line);
404
 		if (cursorEnd.offset == line.length()) {
428
 		if (cursorEnd.offset == line.length()) {
405
 			// merge 2 lines
429
 			// merge 2 lines

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

56
 	}
56
 	}
57
 
57
 
58
 	public void add(ZSToken token) {
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
 	public void addAll(Iterable<ZSToken> tokens) {
62
 	public void addAll(Iterable<ZSToken> tokens) {
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
 		tokens.add(index, token);
92
 		tokens.add(index, token);
71
 		length += token.content.length();
93
 		length += token.content.length();
94
+		return 1;
72
 	}
95
 	}
73
 
96
 
74
 	public void replace(int index, ZSToken token) {
97
 	public void replace(int index, ZSToken token) {

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

273
 					if (!parts[0].isEmpty())
273
 					if (!parts[0].isEmpty())
274
 						currentLine.add(new ZSToken(token.type, parts[0]));
274
 						currentLine.add(new ZSToken(token.type, parts[0]));
275
 					if (!parts[parts.length - 1].isEmpty()) {
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
 					for (int i = 1; i < parts.length - 1; i++) {
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 View File

6
 package org.openzen.zenscript.ide.ui.view.project;
6
 package org.openzen.zenscript.ide.ui.view.project;
7
 
7
 
8
 import org.openzen.drawablegui.DColorableIcon;
8
 import org.openzen.drawablegui.DColorableIcon;
9
+import org.openzen.drawablegui.DMouseEvent;
9
 import org.openzen.drawablegui.live.LiveList;
10
 import org.openzen.drawablegui.live.LiveList;
10
 import org.openzen.drawablegui.live.LiveMappedList;
11
 import org.openzen.drawablegui.live.LiveMappedList;
11
 import org.openzen.zenscript.ide.host.DevelopmentHost;
12
 import org.openzen.zenscript.ide.host.DevelopmentHost;
17
  * @author Hoofdgebruiker
18
  * @author Hoofdgebruiker
18
  */
19
  */
19
 public class ProjectTreeNode extends ProjectOverviewNode {
20
 public class ProjectTreeNode extends ProjectOverviewNode {
21
+	private final IDEWindow window;
20
 	private final DevelopmentHost host;
22
 	private final DevelopmentHost host;
21
 	private final LiveList<ProjectOverviewNode> modules;
23
 	private final LiveList<ProjectOverviewNode> modules;
22
 	
24
 	
23
 	public ProjectTreeNode(IDEWindow window, DevelopmentHost host) {
25
 	public ProjectTreeNode(IDEWindow window, DevelopmentHost host) {
26
+		this.window = window;
24
 		this.host = host;
27
 		this.host = host;
25
 		
28
 		
26
 		modules = new LiveMappedList<>(host.getModules(), module -> new ModuleTreeNode(window, module));
29
 		modules = new LiveMappedList<>(host.getModules(), module -> new ModuleTreeNode(window, module));
50
 	public boolean isLeaf() {
53
 	public boolean isLeaf() {
51
 		return false;
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 View File

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

Loading…
Cancel
Save