2 * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 package org
.lttng
.scope
.tmf2
.views
.ui
.timeline
.widgets
.timegraph
.toolbar
.debugopts
;
12 import static java
.util
.Objects
.requireNonNull
;
14 import java
.util
.stream
.Stream
;
16 import org
.eclipse
.jdt
.annotation
.Nullable
;
17 import org
.lttng
.scope
.tmf2
.views
.core
.config
.ConfigOption
;
18 import org
.lttng
.scope
.tmf2
.views
.ui
.timeline
.DebugOptions
;
20 import com
.google
.common
.primitives
.Doubles
;
21 import com
.google
.common
.primitives
.Ints
;
23 import javafx
.event
.ActionEvent
;
24 import javafx
.geometry
.Insets
;
25 import javafx
.geometry
.Pos
;
26 import javafx
.scene
.Node
;
27 import javafx
.scene
.control
.ButtonBar
.ButtonData
;
28 import javafx
.scene
.control
.ButtonType
;
29 import javafx
.scene
.control
.CheckBox
;
30 import javafx
.scene
.control
.ColorPicker
;
31 import javafx
.scene
.control
.Dialog
;
32 import javafx
.scene
.control
.Label
;
33 import javafx
.scene
.control
.Tab
;
34 import javafx
.scene
.control
.TabPane
;
35 import javafx
.scene
.control
.TextField
;
36 import javafx
.scene
.layout
.HBox
;
37 import javafx
.scene
.layout
.VBox
;
38 import javafx
.scene
.paint
.Color
;
41 * Dialog to configure the debug options at runtime.
43 * @author Alexandre Montplaisir
45 class DebugOptionsDialog
extends Dialog
<@Nullable Void
> {
47 private static final Insets PADDING
= new Insets(20.0);
48 private static final double SPACING
= 10.0;
50 private final DebugOptions fOpts
;
51 private final TabPane fTabPane
;
53 public DebugOptionsDialog(DebugOptionsButton button
) {
54 fOpts
= button
.getDebugOptions();
56 setTitle(Messages
.debugOptionsDialogTitle
);
57 setHeaderText(Messages
.debugOptionsDialogName
);
59 ButtonType resetToDefaultButtonType
= new ButtonType(Messages
.resetDefaultsButtonLabel
, ButtonData
.LEFT
);
60 getDialogPane().getButtonTypes().addAll(resetToDefaultButtonType
, ButtonType
.CANCEL
, ButtonType
.OK
);
62 fTabPane
= new TabPane(getGeneralTab(),
63 getLoadingOverlayTab(),
65 getStateIntervalsTab(),
67 getDialogPane().setContent(fTabPane
);
70 * Restore the last-selected tab (that state is saved in the button),
71 * and re-bind on the new dialog so that the property continues getting
74 fTabPane
.getSelectionModel().select(button
.lastSelectedDialogProperty().get());
75 button
.lastSelectedDialogProperty().bind(fTabPane
.getSelectionModel().selectedIndexProperty());
77 /* What to do when the dialog is closed */
78 setResultConverter(dialogButton
-> {
79 fTabPane
.getSelectionModel().getSelectedIndex();
81 if (dialogButton
!= ButtonType
.OK
) {
85 * Set the debug options according to the current contents of the
88 getAllPropertySetters().forEach(PropertySetter
::save
);
93 /* Define how to "Reset Defaults" button works */
94 getDialogPane().lookupButton(resetToDefaultButtonType
).addEventFilter(ActionEvent
.ACTION
, e
-> {
96 * This button should not close the dialog. Consuming the event here
97 * will prevent the dialog from closing.
101 getAllPropertySetters().forEach(ps
-> {
102 ConfigOption
<?
> option
= ps
.getOption();
103 option
.resetToDefault();
111 private Stream
<PropertySetter
> getAllPropertySetters() {
112 return fTabPane
.getTabs().stream()
113 .flatMap(tab
-> ((VBox
) tab
.getContent()).getChildren().stream())
114 .map(e
-> requireNonNull((PropertySetter
) e
));
117 // ------------------------------------------------------------------------
119 // ------------------------------------------------------------------------
121 private static class DebugOptionsDialogTab
extends Tab
{
123 public DebugOptionsDialogTab(@Nullable String name
, Node
... contents
) {
124 VBox page
= new VBox(contents
);
125 page
.setPadding(PADDING
);
126 page
.setSpacing(SPACING
);
135 private Tab
getGeneralTab() {
136 return new DebugOptionsDialogTab(Messages
.tabNameGeneral
,
137 new CheckBoxControl(Messages
.controlPaintingEnabled
, fOpts
.isPaintingEnabled
),
138 new IntegerTextField(Messages
.controlEntryPadding
, fOpts
.entryPadding
),
139 new DoubleTextField(Messages
.controlRenderRangePadding
, fOpts
.renderRangePadding
),
140 new IntegerTextField(Messages
.controlUIUpdateDelay
, fOpts
.uiUpdateDelay
),
141 new CheckBoxControl(Messages
.controlHScrollEnabled
, fOpts
.isScrollingListenersEnabled
));
144 private Tab
getLoadingOverlayTab() {
145 return new DebugOptionsDialogTab(Messages
.tabNameLoadingOverlay
,
146 new CheckBoxControl(Messages
.controlLoadingOverlayEnabled
, fOpts
.isLoadingOverlayEnabled
),
147 new ColorControl(Messages
.controlLoadingOverlayColor
, fOpts
.loadingOverlayColor
),
148 new DoubleTextField(Messages
.controlLoadingOverlayFullOpacity
, fOpts
.loadingOverlayFullOpacity
),
149 // new DoubleTextField(Messages.controlLoadingOverlayTransparentOpacity, fOpts.loadingOverlayTransparentOpacity),
150 new DoubleTextField(Messages
.controlLoadingOverlayFadeIn
, fOpts
.loadingOverlayFadeInDuration
),
151 new DoubleTextField(Messages
.controlLoadingOverlayFadeOut
, fOpts
.loadingOverlayFadeOutDuration
));
154 private Tab
getZoomTab() {
155 return new DebugOptionsDialogTab(Messages
.tabNameZoom
,
156 new IntegerTextField(Messages
.controlZoomAnimationDuration
+ " (unused)", fOpts
.zoomAnimationDuration
), //$NON-NLS-1$
157 new DoubleTextField(Messages
.controlZoomStep
, fOpts
.zoomStep
),
158 new CheckBoxControl(Messages
.controlZoomPivotOnSelection
, fOpts
.zoomPivotOnSelection
),
159 new CheckBoxControl(Messages
.controlZoomPivotOnMousePosition
, fOpts
.zoomPivotOnMousePosition
));
162 private Tab
getStateIntervalsTab() {
163 return new DebugOptionsDialogTab(Messages
.tabNameIntervals
,
164 new DoubleTextField(Messages
.controlIntervalOpacity
, fOpts
.stateIntervalOpacity
)
165 // multi-state Paint ?
166 // state label Font ?
170 private Tab
getTooltipTab() {
171 return new DebugOptionsDialogTab(Messages
.tabNameTooltips
,
172 // Tooltip Font picker
173 new ColorControl(Messages
.controlTooltipFontColor
, fOpts
.toolTipFontFill
));
176 // ------------------------------------------------------------------------
177 // Property-setting controls
178 // ------------------------------------------------------------------------
180 private static interface PropertySetter
{
181 ConfigOption
<?
> getOption();
186 private static class CheckBoxControl
extends CheckBox
implements PropertySetter
{
188 private final ConfigOption
<Boolean
> fOption
;
190 public CheckBoxControl(@Nullable String labelText
, ConfigOption
<Boolean
> option
) {
197 public ConfigOption
<?
> getOption() {
203 setSelected(fOption
.get());
208 fOption
.set(isSelected());
212 private static class ColorControl
extends HBox
implements PropertySetter
{
214 private final ConfigOption
<Color
> fOption
;
215 private final ColorPicker fColorPicker
;
217 public ColorControl(@Nullable String labelText
, ConfigOption
<Color
> option
) {
220 Label label
= new Label(labelText
+ ":"); //$NON-NLS-1$
221 fColorPicker
= new ColorPicker(option
.get());
223 getChildren().addAll(label
, fColorPicker
);
224 setAlignment(Pos
.CENTER_LEFT
);
229 public ConfigOption
<?
> getOption() {
235 fColorPicker
.setValue(fOption
.get());
240 Color color
= fColorPicker
.getValue();
247 private static abstract class TextFieldControl
<T
extends Number
> extends HBox
implements PropertySetter
{
249 private final ConfigOption
<T
> fOption
;
250 private final TextField fTextField
= new TextField();
252 protected TextFieldControl(@Nullable String labelText
, ConfigOption
<T
> option
) {
255 Label label
= new Label(labelText
+ ":"); //$NON-NLS-1$
258 getChildren().addAll(label
, fTextField
);
259 setAlignment(Pos
.CENTER_LEFT
);
264 public ConfigOption
<T
> getOption() {
270 fTextField
.setText(fOption
.get().toString());
274 public abstract void save();
276 protected TextField
getTextField() {
281 private static class IntegerTextField
extends TextFieldControl
<Integer
> {
283 public IntegerTextField(@Nullable String labelText
, ConfigOption
<Integer
> option
) {
284 super(labelText
, option
);
289 String text
= getTextField().getText();
290 Integer value
= Ints
.tryParse(text
);
292 getOption().resetToDefault();
295 getOption().set(value
);
300 private static class DoubleTextField
extends TextFieldControl
<Double
> {
302 public DoubleTextField(@Nullable String labelText
, ConfigOption
<Double
> option
) {
303 super(labelText
, option
);
308 String text
= getTextField().getText();
309 Double value
= Doubles
.tryParse(text
);
311 getOption().resetToDefault();
314 getOption().set(value
);