1 package net.mograsim.plugin.nature;
3 import java.util.Collections;
4 import java.util.HashSet;
6 import java.util.Optional;
8 import java.util.function.Consumer;
9 import java.util.function.Function;
11 import org.eclipse.core.resources.IProject;
12 import org.eclipse.jface.viewers.ComboViewer;
13 import org.eclipse.jface.viewers.IStructuredContentProvider;
14 import org.eclipse.jface.viewers.LabelProvider;
15 import org.eclipse.jface.viewers.ViewerComparator;
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.widgets.Combo;
18 import org.eclipse.swt.widgets.Composite;
19 import org.eclipse.swt.widgets.Display;
21 import net.mograsim.machine.MachineDefinition;
22 import net.mograsim.machine.MachineRegistry;
23 import net.mograsim.plugin.nature.ProjectContextEvent.ProjectContextEventType;
25 public final class MachineContextSwtTools
27 private static final Map<String, MachineDefinition> INSTALLED_MACHINES = MachineRegistry.getInstalledMachines();
28 private static final Map<IProject, MachineContext> PROJECT_MACHINE_CONTEXTS = ProjectMachineContext.getAllProjectMachineContexts();
30 private MachineContextSwtTools()
35 public static MachineCombo createMachineSelector(Composite parent, int style)
37 return new MachineCombo(parent, style);
40 public static MograsimProjectCombo createMograsimProjectSelector(Composite parent, int style)
42 return new MograsimProjectCombo(parent, style);
45 public abstract static class AdvancedCombo<T>
47 final ComboViewer combo;
48 private Set<Consumer<T>> listeners;
50 public AdvancedCombo(Composite parent, Function<T, String> labelProvider)
52 this(parent, SWT.NONE, labelProvider);
55 public AdvancedCombo(Composite parent, int style, Function<T, String> labelProvider)
57 listeners = Collections.synchronizedSet(new HashSet<>());
58 combo = new ComboViewer(parent, style);
59 combo.addSelectionChangedListener(e -> updateSelection());
60 combo.setComparator(new ViewerComparator());
61 combo.setLabelProvider(new LabelProvider()
63 @SuppressWarnings("unchecked")
65 public String getText(Object element)
69 return labelProvider.apply((T) element);
71 catch (ClassCastException e)
73 return "Invalid Element: " + e.getLocalizedMessage();
79 public final ComboViewer getCombo()
84 @SuppressWarnings("unchecked")
85 public T getSelection()
87 return (T) combo.getStructuredSelection().getFirstElement();
90 private void updateSelection()
92 T active = getSelection();
93 listeners.forEach(l -> l.accept(active));
96 public final void addListener(Consumer<T> listener)
98 listeners.add(listener);
101 public final void removeListener(Consumer<T> listener)
103 listeners.remove(listener);
106 public void refreshContent()
108 Display.getDefault().asyncExec(combo::refresh);
112 public static class MachineCombo extends AdvancedCombo<MachineDefinition>
114 private static final Set<MachineCombo> machineComboListeners = Collections.synchronizedSet(new HashSet<>());
118 MachineRegistry.addMachineRegistryListener(newMap -> machineComboListeners.forEach(AdvancedCombo::refreshContent));
121 public MachineCombo(Composite parent)
123 this(parent, SWT.NONE);
126 public MachineCombo(Composite parent, int style)
128 super(parent, style, MachineDefinition::getId);
129 combo.setContentProvider(new IStructuredContentProvider()
132 public void dispose()
134 machineComboListeners.remove(MachineCombo.this);
138 public Object[] getElements(Object inputElement)
140 return INSTALLED_MACHINES.values().toArray();
143 combo.setInput(this);
144 machineComboListeners.add(this);
148 public static class MograsimProjectCombo extends AdvancedCombo<IProject>
150 private static final Set<MograsimProjectCombo> projectComboListeners = Collections.synchronizedSet(new HashSet<>());
154 ProjectMachineContext.addProjectContextListener(projectEvent ->
156 if (projectEvent.getEventType() != ProjectContextEventType.OTHER_CHANGE)
157 projectComboListeners.forEach(AdvancedCombo::refreshContent);
161 public MograsimProjectCombo(Composite parent)
163 this(parent, SWT.NONE);
166 public MograsimProjectCombo(Composite parent, int style)
168 super(parent, style, IProject::getName);
169 combo.setContentProvider(new IStructuredContentProvider()
172 public void dispose()
174 projectComboListeners.remove(MograsimProjectCombo.this);
178 public Object[] getElements(Object inputElement)
180 return PROJECT_MACHINE_CONTEXTS.values().stream().filter(mc -> mc.getProject().isOpen() && mc.isCurrentyValid())
181 .map(MachineContext::getProject).toArray();
184 combo.setInput(this);
185 projectComboListeners.add(this);
192 static Optional<String> getSelection(Combo c)
194 int selectionIndex = c.getSelectionIndex();
195 if (selectionIndex == -1)
196 return Optional.empty();
197 return Optional.of(c.getItem(selectionIndex));