Tool class for creating Combos that allow to select machines/projects
authorChristian Femers <femers@in.tum.de>
Tue, 24 Sep 2019 04:26:39 +0000 (06:26 +0200)
committerChristian Femers <femers@in.tum.de>
Tue, 24 Sep 2019 04:26:39 +0000 (06:26 +0200)
plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/nature/MachineContextSwtTools.java [new file with mode: 0644]

diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/nature/MachineContextSwtTools.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/nature/MachineContextSwtTools.java
new file mode 100644 (file)
index 0000000..9c0ad0b
--- /dev/null
@@ -0,0 +1,199 @@
+package net.mograsim.plugin.nature;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+import net.mograsim.machine.MachineDefinition;
+import net.mograsim.machine.MachineRegistry;
+import net.mograsim.plugin.nature.ProjectContextEvent.ProjectContextEventType;
+
+public final class MachineContextSwtTools
+{
+       private static final Map<String, MachineDefinition> INSTALLED_MACHINES = MachineRegistry.getInstalledMachines();
+       private static final Map<IProject, MachineContext> PROJECT_MACHINE_CONTEXTS = ProjectMachineContext.getAllProjectMachineContexts();
+
+       private MachineContextSwtTools()
+       {
+               // not instantiable
+       }
+
+       public static MachineCombo createMachineSelector(Composite parent, int style)
+       {
+               return new MachineCombo(parent, style);
+       }
+
+       public static MograsimProjectCombo createMograsimProjectSelector(Composite parent, int style)
+       {
+               return new MograsimProjectCombo(parent, style);
+       }
+
+       public abstract static class AdvancedCombo<T>
+       {
+               final ComboViewer combo;
+               private Set<Consumer<T>> listeners;
+
+               public AdvancedCombo(Composite parent, Function<T, String> labelProvider)
+               {
+                       this(parent, SWT.NONE, labelProvider);
+               }
+
+               public AdvancedCombo(Composite parent, int style, Function<T, String> labelProvider)
+               {
+                       listeners = Collections.synchronizedSet(new HashSet<>());
+                       combo = new ComboViewer(parent, style);
+                       combo.addSelectionChangedListener(e -> updateSelection());
+                       combo.setComparator(new ViewerComparator());
+                       combo.setLabelProvider(new LabelProvider()
+                       {
+                               @SuppressWarnings("unchecked")
+                               @Override
+                               public String getText(Object element)
+                               {
+                                       try
+                                       {
+                                               return labelProvider.apply((T) element);
+                                       }
+                                       catch (ClassCastException e)
+                                       {
+                                               return "Invalid Element: " + e.getLocalizedMessage();
+                                       }
+                               }
+                       });
+               }
+
+               public final ComboViewer getCombo()
+               {
+                       return combo;
+               }
+
+               @SuppressWarnings("unchecked")
+               public T getSelection()
+               {
+                       return (T) combo.getStructuredSelection().getFirstElement();
+               }
+
+               private void updateSelection()
+               {
+                       T active = getSelection();
+                       listeners.forEach(l -> l.accept(active));
+               }
+
+               public final void addListener(Consumer<T> listener)
+               {
+                       listeners.add(listener);
+               }
+
+               public final void removeListener(Consumer<T> listener)
+               {
+                       listeners.remove(listener);
+               }
+
+               public void refreshContent()
+               {
+                       Display.getDefault().asyncExec(combo::refresh);
+               }
+       }
+
+       public static class MachineCombo extends AdvancedCombo<MachineDefinition>
+       {
+               private static final Set<MachineCombo> machineComboListeners = Collections.synchronizedSet(new HashSet<>());
+
+               static
+               {
+                       MachineRegistry.addMachineRegistryListener(newMap -> machineComboListeners.forEach(AdvancedCombo::refreshContent));
+               }
+
+               public MachineCombo(Composite parent)
+               {
+                       this(parent, SWT.NONE);
+               }
+
+               public MachineCombo(Composite parent, int style)
+               {
+                       super(parent, style, MachineDefinition::getId);
+                       combo.setContentProvider(new IStructuredContentProvider()
+                       {
+                               @Override
+                               public void dispose()
+                               {
+                                       machineComboListeners.remove(MachineCombo.this);
+                               }
+
+                               @Override
+                               public Object[] getElements(Object inputElement)
+                               {
+                                       return INSTALLED_MACHINES.values().toArray();
+                               }
+                       });
+                       combo.setInput(this);
+                       machineComboListeners.add(this);
+               }
+       }
+
+       public static class MograsimProjectCombo extends AdvancedCombo<IProject>
+       {
+               private static final Set<MograsimProjectCombo> projectComboListeners = Collections.synchronizedSet(new HashSet<>());
+
+               static
+               {
+                       ProjectMachineContext.addProjectContextListener(projectEvent ->
+                       {
+                               if (projectEvent.getEventType() != ProjectContextEventType.OTHER_CHANGE)
+                                       projectComboListeners.forEach(AdvancedCombo::refreshContent);
+                       });
+               }
+
+               public MograsimProjectCombo(Composite parent)
+               {
+                       this(parent, SWT.NONE);
+               }
+
+               public MograsimProjectCombo(Composite parent, int style)
+               {
+                       super(parent, style, IProject::getName);
+                       combo.setContentProvider(new IStructuredContentProvider()
+                       {
+                               @Override
+                               public void dispose()
+                               {
+                                       projectComboListeners.remove(MograsimProjectCombo.this);
+                               }
+
+                               @Override
+                               public Object[] getElements(Object inputElement)
+                               {
+                                       return PROJECT_MACHINE_CONTEXTS.values().stream().filter(mc -> mc.getProject().isOpen() && mc.isCurrentyValid())
+                                                       .map(MachineContext::getProject).toArray();
+                               }
+                       });
+                       combo.setInput(this);
+                       projectComboListeners.add(this);
+               }
+       }
+
+       /**
+        * XXX: of no use?
+        */
+       static Optional<String> getSelection(Combo c)
+       {
+               int selectionIndex = c.getSelectionIndex();
+               if (selectionIndex == -1)
+                       return Optional.empty();
+               return Optional.of(c.getItem(selectionIndex));
+       }
+}