com.diffplug.common.swt.jface.Actions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of durian-swt Show documentation
Show all versions of durian-swt Show documentation
DurianSwt - Reactive utilities and fluent builders for SWT
The newest version!
/*
* Copyright 2020 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.diffplug.common.swt.jface;
import com.diffplug.common.base.Preconditions;
import com.diffplug.common.swt.SwtMisc;
import java.util.Arrays;
import java.util.Locale;
import java.util.function.BiConsumer;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
/** Provides a fluent interface for constructing actions. */
public class Actions {
/** Style enum for various kinds of IAction. */
public enum Style {
// @formatter:off
PUSH(IAction.AS_PUSH_BUTTON),
CHECK(IAction.AS_CHECK_BOX),
RADIO(IAction.AS_RADIO_BUTTON),
MENU(IAction.AS_DROP_DOWN_MENU);
// @formatter:on
public final int jfaceStyle;
private Style(int jfaceStyle) {
this.jfaceStyle = jfaceStyle;
}
/** Returns the Style of the given IAction. */
public static Style of(IAction action) {
return Arrays.asList(Style.values()).stream()
.filter(style -> style.jfaceStyle == action.getStyle())
.findFirst().get();
}
}
/** Concise method for creating a push action. */
public static IAction create(String text, Runnable action) {
return builder().setText(text).setRunnable(action).build();
}
/** Concise method for creating a push action. */
public static IAction create(String text, ImageDescriptor image, Runnable action) {
return builder().setText(text).setImage(image).setRunnable(action).build();
}
/** Concise method for creating a push action. */
public static IAction create(String text, ImageDescriptor image, int accelerator, Runnable action) {
return builder().setText(text).setImage(image).setAccelerator(accelerator).setRunnable(action).build();
}
/** Concise method for creating a push action. */
public static IAction create(String text, Listener listener) {
return builder().setText(text).setListener(listener).build();
}
/** Concise method for creating a push action. */
public static IAction create(String text, ImageDescriptor image, Listener listener) {
return builder().setText(text).setImage(image).setListener(listener).build();
}
/** Concise method for creating a push action. */
public static IAction create(String text, ImageDescriptor image, int accelerator, Listener listener) {
return builder().setText(text).setImage(image).setAccelerator(accelerator).setListener(listener).build();
}
/** Defaults to a push style with no text, accelerator, or action. */
public static Actions builder() {
return new Actions();
}
/** Action builder that starts with all default values. */
private Actions() {}
private Style style = Style.PUSH;
private String text = "";
private String tooltip = "";
private BiConsumer callback;
private int accelerator = SWT.NONE;
private ImageDescriptor img = null;
/** Copies all behavior from the given action. */
public static Actions builderCopy(IAction action) {
return new Actions(action);
}
private Actions(IAction action) {
this.text = action.getText();
this.style = Style.of(action);
if (action instanceof ActionImp) {
callback = ((ActionImp) action).callback;
} else {
callback = (a, e) -> {
if (e == null) {
action.run();
} else {
action.runWithEvent(e);
}
};
}
this.img = action.getImageDescriptor();
this.accelerator = action.getAccelerator();
this.tooltip = action.getToolTipText();
if (accelerator != SWT.NONE) {
// the toolTip might have had an accelerator added,
// which we'll want to strip so it doesn't get doubled
String hint = getAcceleratorHint(accelerator);
if (tooltip.endsWith(hint)) {
tooltip = tooltip.substring(0, tooltip.length() - hint.length());
}
}
}
/** Sets the text and tooltip. */
public Actions setText(String text) {
this.text = text;
this.tooltip = text;
return this;
}
/** Sets the tooltip. */
public Actions setTooltip(String tooltip) {
this.tooltip = tooltip;
return this;
}
/** Sets the style. */
public Actions setStyle(Style style) {
this.style = style;
return this;
}
/** Sets the callback to be the given Runnable. */
public Actions setRunnable(Runnable run) {
return setCallback((action, event) -> run.run());
}
/** Sets the callback to be the given Listener. It may receive a null event. */
public Actions setListener(Listener listener) {
return setCallback((action, event) -> listener.handleEvent(event));
}
/** Sets the callback to be the given BiConsumer. Action will definitely be present, but event might be missing. */
public Actions setCallback(BiConsumer callback) {
this.callback = callback;
return this;
}
/** Sets the keyboard accelerator. */
public Actions setAccelerator(int accelerator) {
this.accelerator = accelerator;
return this;
}
/** Sets the runnable. */
public Actions setImage(ImageDescriptor img) {
this.img = img;
return this;
}
/** Returns an action with the specified properties. */
public IAction build() {
ActionImp action = new ActionImp(text, style.jfaceStyle, callback);
action.setImageDescriptor(img);
action.setAccelerator(accelerator);
setToolTipAccelAware(action, tooltip);
return action;
}
/** A trivial Action class which delegates its run() method to a Runnable. */
private static class ActionImp extends Action {
private final BiConsumer callback;
private ActionImp(String text, int style, BiConsumer callback) {
super(text, style);
this.callback = callback;
}
@Override
public void run() {
runWithEvent(null);
}
@Override
public void runWithEvent(Event e) {
callback.accept(this, e);
}
}
/** Sets the tooltip text for the given action while remaing aware of its accelerator. */
public static void setToolTipAccelAware(IAction action, String tooltip) {
if (action.getAccelerator() == SWT.NONE) {
action.setToolTipText(tooltip);
} else {
action.setToolTipText(tooltip + getAcceleratorHint(action.getAccelerator()));
}
}
/** Returns a human-readable hint about the accelerator. Must not be passed NO_ACCELERATOR. */
private static String getAcceleratorHint(int accelerator) {
Preconditions.checkArgument(accelerator != SWT.NONE);
return " [" + Actions.getAcceleratorString(accelerator) + "]";
}
/** Returns the given key accelerator as a string (including shift, control, command, etc). */
public static String getAcceleratorString(int accelerator) {
if (accelerator == SWT.NONE) {
return "";
}
StringBuilder builder = new StringBuilder(16);
if (SwtMisc.flagIsSet(SWT.CTRL, accelerator)) {
builder.append("Ctrl ");
accelerator -= SWT.CTRL;
}
if (SwtMisc.flagIsSet(SWT.COMMAND, accelerator)) {
builder.append(UC_CMD + " ");
accelerator -= SWT.COMMAND;
}
if (SwtMisc.flagIsSet(SWT.ALT, accelerator)) {
builder.append("Alt ");
accelerator -= SWT.ALT;
}
if (SwtMisc.flagIsSet(SWT.SHIFT, accelerator)) {
builder.append("Shift ");
accelerator -= SWT.SHIFT;
}
final String end;
if (SWT.F1 <= accelerator && accelerator <= SWT.F20) {
int num = 1 + accelerator - SWT.F1;
end = "F" + Integer.toString(num);
} else {
switch (accelerator) {
case SWT.ARROW_UP:
end = UC_ARROW_UP;
break;
case SWT.ARROW_DOWN:
end = UC_ARROW_DOWN;
break;
case SWT.ARROW_LEFT:
end = UC_ARROW_LEFT;
break;
case SWT.ARROW_RIGHT:
end = UC_ARROW_RIGHT;
break;
case SWT.ESC:
end = "Esc";
break;
case SWT.SPACE:
end = "Spacebar";
break;
default:
end = Character.toString((char) accelerator).toUpperCase(Locale.getDefault());
break;
}
}
builder.append(end);
return builder.toString();
}
/** Unicode for arrows. */
public static final String UC_ARROW_UP = "\u2191";
public static final String UC_ARROW_DOWN = "\u2193";
public static final String UC_ARROW_LEFT = "\u2190";
public static final String UC_ARROW_RIGHT = "\u2192";
/** Unicode for the Mac cmd icon. */
public static final String UC_CMD = "\u2318";
/** Updates the `isChecked()` property of the given IAction (if necessary), then calls IAction::run. */
public static void run(IAction action) {
updateCheckedState(action);
action.run();
}
/** Updates the `isChecked()` property of the given IAction (if necessary), then calls IAction::runWithEvent. */
public static void run(IAction action, Event e) {
updateCheckedState(action);
action.runWithEvent(e);
}
private static void updateCheckedState(IAction action) {
int style = action.getStyle();
if (style == IAction.AS_CHECK_BOX || style == IAction.AS_RADIO_BUTTON) {
action.setChecked(!action.isChecked());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy