001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.gui.dialogs.properties; 003 004 import java.awt.Cursor; 005 import java.awt.Dimension; 006 import java.awt.Font; 007 import java.awt.GridBagLayout; 008 import java.awt.event.MouseEvent; 009 import java.awt.event.MouseListener; 010 import java.awt.font.TextAttribute; 011 import java.util.Collection; 012 import java.util.Collections; 013 import java.util.List; 014 import java.util.Map; 015 016 import javax.swing.Action; 017 import javax.swing.Icon; 018 import javax.swing.JLabel; 019 import javax.swing.JPanel; 020 021 import org.openstreetmap.josm.data.osm.OsmPrimitive; 022 import org.openstreetmap.josm.data.osm.Tag; 023 import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference; 024 import org.openstreetmap.josm.gui.tagging.TaggingPreset; 025 import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType; 026 import org.openstreetmap.josm.tools.GBC; 027 028 public class PresetListPanel extends JPanel { 029 030 public PresetListPanel() { 031 super(new GridBagLayout()); 032 } 033 034 public interface PresetHandler { 035 Collection<OsmPrimitive> getSelection(); 036 void updateTags(List<Tag> tags); 037 } 038 039 /** 040 * Small helper class that manages the highlighting of the label on hover as well as opening 041 * the corresponding preset when clicked 042 */ 043 private static class PresetLabelML implements MouseListener { 044 final JLabel label; 045 final Font hover; 046 final Font normal; 047 final TaggingPreset tag; 048 final PresetHandler presetHandler; 049 050 PresetLabelML(JLabel lbl, TaggingPreset t, PresetHandler presetHandler) { 051 super(); 052 label = lbl; 053 lbl.setCursor(new Cursor(Cursor.HAND_CURSOR)); 054 normal = label.getFont(); 055 hover = normal.deriveFont(Collections.singletonMap(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DOTTED)); 056 tag = t; 057 this.presetHandler = presetHandler; 058 } 059 public void mouseClicked(MouseEvent arg0) { 060 Collection<OsmPrimitive> selection = tag.createSelection(presetHandler.getSelection()); 061 if (selection == null || selection.isEmpty()) 062 return; 063 int answer = tag.showDialog(selection, false); 064 065 if (answer == TaggingPreset.DIALOG_ANSWER_APPLY) { 066 presetHandler.updateTags(tag.getChangedTags()); 067 } 068 069 } 070 public void mouseEntered(MouseEvent arg0) { 071 label.setFont(hover); 072 } 073 public void mouseExited(MouseEvent arg0) { 074 label.setFont(normal); 075 } 076 public void mousePressed(MouseEvent arg0) {} 077 public void mouseReleased(MouseEvent arg0) {} 078 } 079 080 public void updatePresets(final Collection<PresetType> types, final Map<String, String> tags, PresetHandler presetHandler) { 081 082 removeAll(); 083 if (types.isEmpty()) { 084 setVisible(false); 085 return; 086 } 087 088 for (TaggingPreset t : TaggingPresetPreference.taggingPresets) { 089 if (!t.matches(types, tags, true)) { 090 continue; 091 } 092 093 JLabel lbl = new JLabel(t.getName() + " ???"); 094 lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON)); 095 lbl.addMouseListener(new PresetLabelML(lbl, t, presetHandler)); 096 add(lbl, GBC.eol().fill(GBC.HORIZONTAL)); 097 } 098 099 if (getComponentCount() > 0) { 100 setVisible(true); 101 // This ensures the presets are exactly as high as needed. 102 int height = getComponentCount() * getComponent(0).getHeight(); 103 Dimension size = new Dimension(getWidth(), height); 104 setMaximumSize(size); 105 setMinimumSize(size); 106 } else { 107 setVisible(false); 108 } 109 } 110 }