Commit | Line | Data |
---|---|---|
735b1ca2 AM |
1 | package org.lttng.scope.tmf2.views.ui.jfx.testapp; |
2 | ||
3 | import static java.util.Objects.requireNonNull; | |
4 | ||
5 | import java.util.stream.DoubleStream; | |
6 | import java.util.stream.Stream; | |
7 | ||
8 | import org.eclipse.jdt.annotation.Nullable; | |
9 | import org.lttng.scope.tmf2.views.ui.jfx.JfxUtils; | |
10 | ||
11 | import javafx.application.Application; | |
12 | import javafx.scene.Group; | |
13 | import javafx.scene.Scene; | |
14 | import javafx.scene.control.ScrollPane; | |
15 | import javafx.scene.control.ScrollPane.ScrollBarPolicy; | |
16 | import javafx.scene.layout.BorderPane; | |
17 | import javafx.scene.layout.Pane; | |
18 | import javafx.scene.paint.Color; | |
19 | import javafx.scene.shape.Line; | |
20 | import javafx.scene.shape.Rectangle; | |
21 | import javafx.scene.shape.StrokeLineCap; | |
22 | import javafx.stage.Stage; | |
23 | ||
24 | public class UiModelApp extends Application { | |
25 | ||
26 | /* Value where a raw Pane starts breaking down */ | |
27 | private static final double PANE_WIDTH = 1000000000.0; | |
28 | /* Maximum pane width (roughly a 1-year trace at 0.01 nanos/pixel) */ | |
29 | // private static final double PANE_WIDTH = 1e16; | |
30 | ||
31 | private static final double MAX_WIDTH = 1000000.0; | |
32 | ||
33 | private static final double ENTRY_HEIGHT = 20; | |
34 | private static final Color BACKGROUD_LINES_COLOR = requireNonNull(Color.LIGHTBLUE); | |
35 | private static final String BACKGROUND_STYLE = "-fx-background-color: rgba(255, 255, 255, 255);"; //$NON-NLS-1$ | |
36 | ||
37 | private static final double SELECTION_STROKE_WIDTH = 1; | |
38 | private static final Color SELECTION_STROKE_COLOR = requireNonNull(Color.BLUE); | |
39 | private static final Color SELECTION_FILL_COLOR = requireNonNull(Color.LIGHTBLUE.deriveColor(0, 1.2, 1, 0.4)); | |
40 | ||
41 | public static void main(String[] args) { | |
42 | launch(args); | |
43 | } | |
44 | ||
45 | @Override | |
46 | public void start(@Nullable Stage primaryStage) throws Exception { | |
47 | if (primaryStage == null) { | |
48 | return; | |
49 | } | |
50 | ||
51 | /* Layers */ | |
52 | Group backgroundLayer = new Group(); | |
53 | Group statesLayer = new Group(); | |
54 | Group selectionLayer = new Group(); | |
55 | ||
56 | /* Top-level */ | |
57 | Pane contentPane = new Pane(backgroundLayer, statesLayer, selectionLayer); | |
58 | contentPane.minWidthProperty().bind(contentPane.prefWidthProperty()); | |
59 | contentPane.maxWidthProperty().bind(contentPane.prefWidthProperty()); | |
60 | contentPane.setStyle(BACKGROUND_STYLE); | |
61 | ||
62 | ScrollPane scrollPane = new ScrollPane(contentPane); | |
63 | scrollPane.setVbarPolicy(ScrollBarPolicy.ALWAYS); | |
64 | scrollPane.setHbarPolicy(ScrollBarPolicy.ALWAYS); | |
65 | scrollPane.setFitToHeight(true); | |
66 | scrollPane.setFitToWidth(true); | |
67 | scrollPane.setPannable(true); | |
68 | ||
69 | BorderPane borderPane = new BorderPane(scrollPane); | |
70 | ||
71 | primaryStage.setScene(new Scene(borderPane)); | |
72 | primaryStage.show(); | |
73 | primaryStage.setHeight(500); | |
74 | primaryStage.setWidth(500); | |
75 | ||
76 | contentPane.setPrefHeight(200); | |
77 | contentPane.setPrefWidth(PANE_WIDTH); | |
78 | ||
79 | drawBackground(backgroundLayer, contentPane); | |
80 | drawRectangles(statesLayer); | |
81 | drawSelection(selectionLayer, contentPane); | |
82 | } | |
83 | ||
84 | private static void drawBackground(Group parent, Pane content) { | |
85 | DoubleStream.iterate(ENTRY_HEIGHT / 2, i -> i + ENTRY_HEIGHT).limit(10) | |
86 | .mapToObj(y -> { | |
87 | Line line = new Line(); | |
88 | line.setStartX(0); | |
89 | line.endXProperty().bind(content.widthProperty()); | |
90 | // line.setEndX(MAX_WIDTH); | |
91 | line.setStartY(y); | |
92 | line.setEndY(y); | |
93 | ||
94 | line.setStroke(BACKGROUD_LINES_COLOR); | |
95 | line.setStrokeWidth(1.0); | |
96 | return line; | |
97 | }) | |
98 | .forEach(parent.getChildren()::add); | |
99 | } | |
100 | ||
101 | private static void drawRectangles(Group target) { | |
102 | DrawnRectangle rectangle1 = new DrawnRectangle(1, PANE_WIDTH - 20, 2); | |
103 | rectangle1.setFill(Color.GREEN); | |
104 | ||
105 | DrawnRectangle rectangle2 = new DrawnRectangle(20, 2000, 5); | |
106 | rectangle2.setFill(Color.RED); | |
107 | ||
108 | DrawnRectangle rectangle3 = new DrawnRectangle(PANE_WIDTH - 2000, PANE_WIDTH - 100, 6); | |
109 | rectangle3.setFill(Color.ORANGE); | |
110 | ||
111 | target.getChildren().addAll(rectangle1, rectangle2, rectangle3); | |
112 | } | |
113 | ||
114 | ||
115 | private static class DrawnRectangle extends Rectangle { | |
116 | ||
117 | private static final double THICKNESS = 10; | |
118 | ||
119 | public DrawnRectangle(double startX, double endX, int entryIndex) { | |
120 | double y0 = entryIndex * ENTRY_HEIGHT; | |
121 | double yOffset = (ENTRY_HEIGHT - THICKNESS) / 2; | |
122 | ||
123 | // double width = endX - startX; | |
124 | double width = Math.min(endX - startX, MAX_WIDTH); | |
125 | ||
126 | setX(startX); | |
127 | setY(y0 + yOffset); | |
128 | setWidth(width); | |
129 | setHeight(THICKNESS); | |
130 | } | |
131 | } | |
132 | ||
133 | private static void drawSelection(Group parent, Pane content) { | |
134 | Rectangle selection1 = new Rectangle(); | |
135 | Rectangle selection2 = new Rectangle(); | |
136 | ||
137 | Stream.of(selection1, selection2).forEach(rect -> { | |
138 | rect.setMouseTransparent(true); | |
139 | ||
140 | rect.setStroke(SELECTION_STROKE_COLOR); | |
141 | rect.setStrokeWidth(SELECTION_STROKE_WIDTH); | |
142 | rect.setStrokeLineCap(StrokeLineCap.ROUND); | |
143 | rect.setFill(SELECTION_FILL_COLOR); | |
144 | ||
145 | rect.yProperty().bind(JfxUtils.ZERO_PROPERTY); | |
146 | rect.heightProperty().bind(content.heightProperty()); | |
147 | }); | |
148 | ||
149 | selection1.setX(200); | |
150 | selection1.setWidth(100); | |
151 | ||
152 | selection2.setX(PANE_WIDTH - 1000); | |
153 | selection2.setWidth(500); | |
154 | ||
155 | parent.getChildren().addAll(selection1, selection2); | |
156 | } | |
157 | } |