| 
Tried it, that’s kinda cool.
   One comment, maybe display the message on top left or above the cursor so you can read easier.   Don   From: nebula-dev [mailto:nebula-dev-bounces@xxxxxxxxxxx]
On Behalf Of Wim JongmanSent: Wednesday, April 7, 2021 9:19 AM
 To: Nebula Dev <nebula-dev@xxxxxxxxxxx>
 Subject: [EXTERNAL] Re: [nebula-dev] Urgent Nebula bugs to tackle?
   
| 
|  | 
EXT email: be mindful of links/attachments. |  
 |  
Sometimes we want to give the user a little feedback. "Saved!", "Please wait...", "Loading..", without having to resort to those bulky dialogs.
 
For these use cases, we have invented MiniMessage. MM can display a small message at the current mouse pointer or above a specific control.
 
Just paste the source code below into a UI project package and run as java application. It would be nice if this would make it into Nebula 
It would be nice if the message box could be round/square/balloon/closable, etc.. 
Let me know what you think. 
/******************************************************************************** Copyright (c) 2021 Remain Software -  http://remainsoftware.com
 * All rights reserved. This program is made available under the terms
 * of the Eclipse Public License v1.0 which does not accompanies this
 * distribution but is available at 
http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Wim Jongman - Initial Impl
 *******************************************************************************/
 
 package com.remainsoftware.common.licensing.util;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.PlatformUI;
 
 /**
 * Shows a mini message for those cases when you want to supply a quick feedback
 * to the user without going through the workflow of showing a dialog and
 * letting the user press Ok.
 * <p/>
 * Usage:
 * <p/>
 * <code>
 * // Show mini message just above cursor position
 * MiniMessage.get(2000).open("Saved!");
 * // Show mini message just above this control
 * MiniMessage(2000).get(1000).above(Control).open("Saved!");
 * </code>
 *
 * @author Wim Jongman
 *
 */
 public class MiniMessage {
 
 public static void main(String[] args) {
 Display display = new Display();
 MiniMessage.get(2000).openWait("Hello, World!");
 display.dispose();
 }
 
 /** Error message */
 public static final String ERROR = "E";
 /** Info message (default) */
 public static final String INFO = "I";
 /** Warning message */
 public static final String WARNING = "W";
 
 private StyledText fStyledText;
 private Shell fShell;
 private int fWaitBeforeFade = 0;
 private Control fControl;
 private String fType = INFO;
 
 /**
 * Constructs a {@link MiniMessage}.
 *
 * @param waitBeforeFade waits n milliseconds before the message starts to fade.
 *                       Fading itself takes about a second.
 */
 private MiniMessage(int waitBeforeFade) {
 this.fWaitBeforeFade = waitBeforeFade;
 }
 
 /**
 * Factory method to get a new MiniMessage.
 *
 * @param pWaitBeforeFade
 * @return
 */
 public static MiniMessage get(int pWaitBeforeFade) {
 return new MiniMessage(pWaitBeforeFade);
 }
 
 public MiniMessage above(Control pControl) {
 this.fControl = pControl;
 return this;
 }
 
 /**
 * Opens the {@link MiniMessage} just above the current cursor position showing
 * the passed text. It does not wait until the message has faded.
 *
 * @param text the text to show as the mini message.
 *
 * @see #openWait(String)
 */
 public void openWait(String message) {
 doOpen(message, true);
 }
 
 /**
 * Submits the mini message to the UI queue so that it is processed at the next
 * convenience. Use this is you want to show some message after for example the
 * createPartControl method in a view has finished.
 *
 * Must be called from the UI thread.
 *
 * @param text the text to show as the mini message.
 *
 * @see #open(String)
 * @see #openWait(String)
 */
 public void submit(final String text) {
 Runnable runner = () -> doOpen(text, false);
 Display.getCurrent().asyncExec(runner);
 }
 
 /**
 * Opens the {@link MiniMessage} just above the current cursor position showing
 * the passed text. It does not wait until the message has faded.
 *
 * @param text the text to show as the mini message.
 *
 * @see #openWait(String)
 */
 public void open(String text) {
 doOpen(text, false);
 }
 
 private void doOpen(String text, boolean wait) {
 try {
 Display display = Display.getDefault();
 fShell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP | SWT.NO_FOCUS);
 GridLayout gridLayout = new GridLayout(1, false);
 gridLayout.marginWidth = 1;
 gridLayout.marginHeight = 1;
 gridLayout.verticalSpacing = 0;
 gridLayout.horizontalSpacing = 0;
 createContents(fShell, SWT.NONE);
 setText(text);
 Control focusControl = display.getFocusControl();
 fShell.setLayout(gridLayout);
 fShell.pack();
 fShell.setLocation(getLocation());
 fShell.open();
 fShell.layout();
 if (focusControl != null) {
 focusControl.forceFocus();
 }
 Thread thread = new Thread(new Fader(fWaitBeforeFade));
 thread.run();
 while (wait && !fShell.isDisposed()) {
 if (!display.readAndDispatch()) {
 display.sleep();
 }
 }
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 
 private Point getLocation() {
 if (fControl == null || fControl.isDisposed() || fControl.getParent() == null) {
 Display display = Display.getDefault();
 return display.getCursorLocation();
 }
 return fControl.getParent().toDisplay(
 fControl.getLocation().x + (fControl.getSize().x / 2) - (fShell.getSize().x / 2),
 fControl.getLocation().y - fControl.getSize().y - 10);
 }
 
 private void setText(String string) {
 fStyledText.setText(string);
 }
 
 /**
 * Create the composite.
 *
 * @param parent
 * @param style
 */
 private void createContents(Composite parent, int style) {
 GridLayout gridLayout = new GridLayout();
 gridLayout.marginWidth = 9;
 gridLayout.marginHeight = 9;
 parent.setLayout(gridLayout);
 fStyledText = new StyledText(parent, SWT.BORDER);
 fStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
 fStyledText.setEditable(false);
 fStyledText.setEnabled(false);
 if (ERROR.equals(fType)) {
 fStyledText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_RED));
 fStyledText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
 }
 if (WARNING.equals(fType)) {
 fStyledText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));
 fStyledText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
 } else {
 fStyledText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN));
 fStyledText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
 }
 }
 
 private class Fader implements Runnable {
 int fAlpha = 255;
 private int fTimerWait = 10;
 private int fWaitBeforeFade = 0;
 
 public Fader(int waitBeforeFade) {
 this.fWaitBeforeFade = waitBeforeFade;
 }
 
 @Override
 public void run() {
 if (fWaitBeforeFade > 0) {
 fShell.getDisplay().timerExec(fWaitBeforeFade, this);
 fWaitBeforeFade = 0;
 } else if (fAlpha <= 5) {
 fShell.dispose();
 } else {
 fAlpha -= 5;
 if (fAlpha < 255) {
 fShell.setAlpha(fAlpha);
 }
 fShell.getDisplay().timerExec(fTimerWait, this);
 }
 }
 }
 
 /**
 * Sets the type. If the type is not any of the valid values then
 * {@link MiniMessage#INFO} will be assumed.
 *
 * @param pType
 * @return this object for chaining
 *
 * @see #ERROR
 * @see #WARNING
 * @see #INFO
 */
 public MiniMessage setType(String pType) {
 fType = pType;
 return this;
 }
 }
   |