/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2014, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.gui.javafx.contexttree; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.util.EventObject; import javafx.beans.value.ObservableValue; import javafx.embed.swing.SwingFXUtils; import javafx.event.ActionEvent; import javafx.geometry.Insets; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ButtonBar; import javafx.scene.control.Tooltip; import javafx.scene.control.TreeTableCell; import javafx.scene.control.TreeTableColumn; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.util.Callback; import org.geotoolkit.display2d.service.DefaultGlyphService; import org.geotoolkit.gui.javafx.layer.style.FXStyleAggregatedPane; import org.geotoolkit.internal.GeotkFX; import org.geotoolkit.map.LayerListener; import org.geotoolkit.map.MapItem; import org.geotoolkit.map.MapLayer; import org.geotoolkit.util.collection.CollectionChangeEvent; /** * * @author Johann Sorel (Geomatys) * @author Alexis Manin (Geomatys) */ public class MapItemGlyphColumn extends TreeTableColumn { public MapItemGlyphColumn() { setCellValueFactory(new Callback<CellDataFeatures, ObservableValue>() { @Override public ObservableValue call(CellDataFeatures cellData) { return cellData.getValue().valueProperty(); } }); setCellFactory(new Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>>() { @Override public TreeTableCell<Object, Object> call(TreeTableColumn<Object, Object> column) { return new MapItemGlyphTableCell(); } }); setEditable(true); setPrefWidth(34); setMinWidth(34); setMaxWidth(34); } protected Pane createEditor(MapLayer candidate) { FXStyleAggregatedPane pane = new FXStyleAggregatedPane(); pane.init(candidate); return pane; } protected void openEditor(Node owner,MapLayer candidate) { final Pane panel = createEditor(candidate); panel.setPrefSize(900, 700); final Stage dialog = new Stage(); dialog.initModality(Modality.NONE); dialog.initOwner(owner.getScene().getWindow()); dialog.setTitle(GeotkFX.getString("org.geotoolkit.gui.javafx.contexttree.MapItemGlyphColumn.dialogTitle") + candidate.getName()); dialog.setResizable(true); final Button cancelBtn = new Button(GeotkFX.getString("org.geotoolkit.gui.javafx.contexttree.menu.LayerPropertiesItem.close")); cancelBtn.setCancelButton(true); final ButtonBar bbar = new ButtonBar(); bbar.setPadding(new Insets(5, 5, 5, 5)); bbar.getButtons().addAll(cancelBtn); final BorderPane dialogContent = new BorderPane(); dialogContent.setCenter(panel); dialogContent.setBottom(bbar); dialog.setScene(new Scene(dialogContent)); dialog.getScene().getStylesheets().setAll(owner.getScene().getStylesheets()); cancelBtn.setOnAction((ActionEvent e) -> { dialog.close(); }); dialog.show(); } private class MapItemGlyphTableCell extends TreeTableCell implements LayerListener{ private final LayerListener.Weak listener = new LayerListener.Weak(this); private MapLayer mapLayer; /** Image view contained in the cell. */ private final ImageView cellContent = new ImageView(); public MapItemGlyphTableCell() { setOnMouseClicked(this::mouseClick); setTooltip(new Tooltip(GeotkFX.getString(MapItemGlyphColumn.class, "tooltip"))); } private void mouseClick(MouseEvent event){ event.consume(); Object candidate = getItem(); if (candidate instanceof MapLayer) { openEditor(MapItemGlyphTableCell.this,(MapLayer)candidate); } } @Override protected void updateItem(Object mapItem, boolean empty) { super.updateItem(mapItem, empty); mapLayer = null; listener.dispose(); setGraphic(null); if (!empty && mapItem instanceof MapLayer) { mapLayer = (MapLayer) mapItem; listener.registerSource(mapLayer); cellContent.setImage(createGlyph(mapLayer)); setGraphic(cellContent); } } @Override public void propertyChange(PropertyChangeEvent evt) { if(MapLayer.STYLE_PROPERTY.equals(evt.getPropertyName())){ cellContent.setImage(createGlyph(mapLayer)); } } @Override public void styleChange(MapLayer source, EventObject event) { cellContent.setImage(createGlyph(mapLayer)); } @Override public void itemChange(CollectionChangeEvent<MapItem> event) {} } private static Image createGlyph(final MapLayer mapLayer) { if (mapLayer != null) { final BufferedImage glyph = new BufferedImage(24, 16, BufferedImage.TYPE_INT_ARGB); DefaultGlyphService.render(mapLayer.getStyle(), new Rectangle(24, 16), glyph.createGraphics(), mapLayer); return SwingFXUtils.toFXImage(glyph, null); } return null; } }