Skip to content
This repository has been archived by the owner on Nov 20, 2023. It is now read-only.

Commit

Permalink
timegraph: Add menu button to create custom event series
Browse files Browse the repository at this point in the history
Since the current time graph models do not provide event series
themselves, we can offer a way to create some from the UI for simple
(and demo) purposes.

Eventually this custom series creation could be moved outside of the
timegraph widget.

Refs #9.

Signed-off-by: Alexandre Montplaisir <[email protected]>
  • Loading branch information
Alexandre Montplaisir committed May 1, 2017
1 parent 2f79d89 commit 4298a04
Show file tree
Hide file tree
Showing 8 changed files with 541 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import javafx.scene.shape.SVGPath;
import javafx.scene.shape.Shape;

class TimeGraphDrawnEventControl {
public class TimeGraphDrawnEventControl {

private final TimeGraphWidget fWidget;
private final Group fParentGroup;
Expand Down Expand Up @@ -179,18 +179,24 @@ private Collection<Shape> prepareDrawnEvents(TimeGraphTreeRender treeRender, Tim
private static Shape getShapeFromEvent(TimeGraphDrawnEvent event) {
Color color = JfxColorFactory.getColorFromDef(event.getEventSeries().getColor().get());
SymbolStyle symbol = event.getEventSeries().getSymbolStyle().get();
Shape shape = getShapeFromSymbol(symbol);
shape.setFill(color);
return shape;
}

public static Shape getShapeFromSymbol(SymbolStyle symbol) {
Shape shape;
switch (symbol) {
case CIRCLE:
shape = new Circle(5);
break;

case DIAMOND: {
SVGPath path = new SVGPath();
path.setContent("M5,0 L10,9 L5,18 L0,9 Z"); //$NON-NLS-1$
path.relocate(-5, -9);
shape = path;
shape = new Polygon(5.0, 0.0,
10.0, 5.0,
5.0, 10.0,
0.0, 5.0);
shape.relocate(-5.0, -5.0);
}
break;

Expand Down Expand Up @@ -232,7 +238,6 @@ private static Shape getShapeFromEvent(TimeGraphDrawnEvent event) {

}

shape.setFill(color);
shape.setStroke(Color.BLACK);
return shape;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.StateRectangle;
import org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.TimeGraphWidget;
import org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.toolbar.debugopts.DebugOptionsButton;
import org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.toolbar.drawnevents.EventSeriesMenuButton;
import org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.toolbar.modelconfig.ModelConfigButton;
import org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.toolbar.nav.NavigationButtons;

Expand Down Expand Up @@ -63,11 +64,12 @@ public ViewerToolBar(TimeGraphWidget viewer) {
navButtons.getForwardButton(),
navButtons.getMenuButton()
),
getStateInfoButton(viewer),
new Separator(),

new ModelConfigButton(viewer),
getStateInfoButton(viewer),
new ArrowSeriesMenuButton(viewer),
new EventSeriesMenuButton(viewer),
new SortingModeMenuButton(viewer),
new FilterModeMenuButton(viewer),
new Separator(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <[email protected]>
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.toolbar.drawnevents;

import java.util.function.Predicate;

import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.lttng.scope.tmf2.views.core.config.ConfigOption;
import org.lttng.scope.tmf2.views.core.timegraph.model.provider.ITimeGraphModelProvider;
import org.lttng.scope.tmf2.views.core.timegraph.model.render.ColorDefinition;
import org.lttng.scope.tmf2.views.core.timegraph.model.render.drawnevents.TimeGraphDrawnEventSeries;
import org.lttng.scope.tmf2.views.core.timegraph.model.render.drawnevents.TimeGraphDrawnEventSeries.SymbolStyle;
import org.lttng.scope.tmf2.views.ui.jfx.CountingGridPane;
import org.lttng.scope.tmf2.views.ui.jfx.JfxColorFactory;
import org.lttng.scope.tmf2.views.ui.timeline.widgets.timegraph.TimeGraphDrawnEventControl;

import javafx.beans.property.ReadOnlyProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Shape;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.util.Callback;

class CreateEventSeriesDialog extends Dialog<@Nullable PredicateDrawnEventProvider> {

private static final Color DEFAULT_SYMBOL_COLOR = Color.ORANGE;
private static final double PADDING = 10;

private static final Font HEADER_FONT = Font.font(null, FontWeight.BOLD, FontPosture.REGULAR, -1);
private static final Insets HEADER_PADDING = new Insets(10, 0, 10, 0);

private final TextField fEventNameField;

private final ColorPicker fSymbolColorPicker;
private final ShapePicker fSymbolShapePicker;

public CreateEventSeriesDialog(ITimeGraphModelProvider modelProvider) {
setTitle(Messages.createEventSeriesDialogTitle);

/* Dialog buttons, standard "OK" and "Cancel" */
getDialogPane().getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK);

/* Dialog contents */
Label filterHeader = new Label(Messages.createEventSeriesDialogSectionFilterDef);
filterHeader.setFont(HEADER_FONT);
filterHeader.setPadding(HEADER_PADDING);

fEventNameField = new TextField();
CountingGridPane filterGrid = new CountingGridPane();
filterGrid.setHgap(PADDING);
filterGrid.setVgap(PADDING);
filterGrid.appendRow(new Label(Messages.createEventSeriesDialogFieldEventName), fEventNameField);

Label symbolHeader = new Label(Messages.createEventSeriesDialogSectionSymbolDef);
symbolHeader.setFont(HEADER_FONT);
symbolHeader.setPadding(HEADER_PADDING);

fSymbolColorPicker = new ColorPicker(DEFAULT_SYMBOL_COLOR);
fSymbolShapePicker = new ShapePicker(fSymbolColorPicker.valueProperty());
CountingGridPane symbolGrid = new CountingGridPane();
symbolGrid.setHgap(PADDING);
symbolGrid.setVgap(PADDING);
symbolGrid.appendRow(new Label(Messages.createEventSeriesDialogFieldColor), fSymbolColorPicker);
symbolGrid.appendRow(new Label(Messages.createEventSeriesDialogFieldShape), fSymbolShapePicker);

VBox vbox = new VBox(filterHeader, filterGrid, symbolHeader, symbolGrid);
vbox.setAlignment(Pos.CENTER);
getDialogPane().setContent(vbox);

/*
* Disable the OK button until the input is valid
*
* TODO ControlsFX Validation framework might be useful when more
* fields/options are added.
*/
final Button okButton = (Button) getDialogPane().lookupButton(ButtonType.OK);
okButton.setDisable(true);
fEventNameField.textProperty().addListener((observable, oldValue, newValue) -> {
okButton.setDisable(newValue.trim().length() <= 0);
});

/* What to do when the dialog is closed */
setResultConverter(dialogButton -> {
if (dialogButton != ButtonType.OK) {
return null;
}

String eventName = fEventNameField.getText();
if (eventName == null || eventName.isEmpty()) {
return null;
}

TimeGraphDrawnEventSeries series = generateEventSeries();
Predicate<ITmfEvent> predicate = event -> event.getName().equals(eventName);
return new PredicateDrawnEventProvider(series, modelProvider, predicate);
});

}

/**
* Generate an event series from the current value of the controls
*
* @return The corresponding event series
*/
private TimeGraphDrawnEventSeries generateEventSeries() {
String seriesName = fEventNameField.getText();
ColorDefinition colorDef = JfxColorFactory.colorToColorDef(fSymbolColorPicker.getValue());
SymbolStyle style = fSymbolShapePicker.getSelectionModel().getSelectedItem();

return new TimeGraphDrawnEventSeries(
seriesName == null ? "" : seriesName, //$NON-NLS-1$
new ConfigOption<>(colorDef),
new ConfigOption<>(style));
}

private static class ShapePicker extends ComboBox<SymbolStyle> {

public ShapePicker(ReadOnlyProperty<Color> colorSource) {
getItems().addAll(SymbolStyle.values());

Callback<@Nullable ListView<SymbolStyle>, ListCell<SymbolStyle>> cellFactory =
p -> new ListCell<SymbolStyle>() {
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}

@Override
protected void updateItem(SymbolStyle item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
Node graphic = getGraphicFromSymbol(item, colorSource);
setGraphic(graphic);
}
}
};

setButtonCell(cellFactory.call(null));
setCellFactory(cellFactory);

/* Select the first symbol by default */
getSelectionModel().select(0);
}

private static Node getGraphicFromSymbol(SymbolStyle symbol, ReadOnlyProperty<Color> colorSource) {
Shape graphic = TimeGraphDrawnEventControl.getShapeFromSymbol(symbol);
graphic.fillProperty().bind(colorSource);
return graphic;
}

}

}
Loading

0 comments on commit 4298a04

Please sign in to comment.