diff --git a/rap/src/main/resources/org/apache/hop/ui/hopgui/dark-mode.css b/rap/src/main/resources/org/apache/hop/ui/hopgui/dark-mode.css index 1746db4aac6..a7bf859b866 100644 --- a/rap/src/main/resources/org/apache/hop/ui/hopgui/dark-mode.css +++ b/rap/src/main/resources/org/apache/hop/ui/hopgui/dark-mode.css @@ -183,6 +183,13 @@ Button[TOGGLE][FLAT] { text-shadow: none; } +/* Compact padding so a 16px help icon fits the same height as text-only OK/Cancel. */ +Button[PUSH].helpButton, +Button[PUSH][BORDER].helpButton, +Button[PUSH][FLAT].helpButton { + padding: 4px 12px; +} + Button[ARROW], Button[ARROW][BORDER], Button[ARROW][FLAT] { diff --git a/rap/src/main/resources/org/apache/hop/ui/hopgui/light-mode.css b/rap/src/main/resources/org/apache/hop/ui/hopgui/light-mode.css index 0d0179c4563..0287216aa69 100644 --- a/rap/src/main/resources/org/apache/hop/ui/hopgui/light-mode.css +++ b/rap/src/main/resources/org/apache/hop/ui/hopgui/light-mode.css @@ -181,6 +181,13 @@ Button[TOGGLE][FLAT] { text-shadow: 0 1px 0 #ffffff; } +/* Compact padding so a 16px help icon fits the same height as text-only OK/Cancel. */ +Button[PUSH].helpButton, +Button[PUSH][BORDER].helpButton, +Button[PUSH][FLAT].helpButton { + padding: 4px 12px; +} + Button[ARROW], Button[ARROW][BORDER], Button[ARROW][FLAT] { diff --git a/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java b/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java index 20c33452b9b..f3723107b9a 100644 --- a/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java +++ b/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java @@ -30,6 +30,7 @@ import org.apache.hop.ui.core.widget.StyledTextComp; import org.apache.hop.ui.core.widget.TextComposite; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; +import org.apache.hop.ui.util.HelpUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.CTabFolder; @@ -167,13 +168,13 @@ public NotePadMeta open() { // Help (Markdown notes) — bottom-left, same placement as transform/action dialogs Button wHelp = new Button(shell, SWT.PUSH); PropsUi.setLook(wHelp); - wHelp.setImage(GuiResource.getInstance().getImageHelp()); wHelp.setText(BaseMessages.getString(PKG, "NotePadDialog.Help.Button")); wHelp.setToolTipText(BaseMessages.getString(PKG, "NotePadDialog.Markdown.Help.Tooltip")); FormData fdHelp = new FormData(); fdHelp.left = new FormAttachment(0, 0); fdHelp.bottom = new FormAttachment(100, 0); wHelp.setLayoutData(fdHelp); + HelpUtils.applyHelpButtonImage(wHelp); wHelp.addListener(SWT.Selection, e -> MarkdownNoteHelp.show(shell)); wNoteFolder = new CTabFolder(shell, SWT.BORDER); diff --git a/ui/src/main/java/org/apache/hop/ui/util/HelpUtils.java b/ui/src/main/java/org/apache/hop/ui/util/HelpUtils.java index 8c5e1f0ee26..11826abaa1c 100644 --- a/ui/src/main/java/org/apache/hop/ui/util/HelpUtils.java +++ b/ui/src/main/java/org/apache/hop/ui/util/HelpUtils.java @@ -30,6 +30,7 @@ import org.apache.hop.core.util.StringUtil; import org.apache.hop.core.util.Utils; import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.ui.core.ConstUi; import org.apache.hop.ui.core.PropsUi; import org.apache.hop.ui.core.dialog.BaseDialog; import org.apache.hop.ui.core.dialog.ErrorDialog; @@ -49,6 +50,8 @@ public class HelpUtils { private static final Class PKG = HelpUtils.class; + private static final String RAP_CUSTOM_VARIANT = "org.eclipse.rap.rwt.customVariant"; + private static final String HELP_BUTTON_VARIANT = "helpButton"; public static Button createHelpButton(final Composite parent, final IPlugin plugin) { Button button = newButton(parent); @@ -65,18 +68,56 @@ public static Button createHelpButton(final Composite parent, final String url) private static Button newButton(final Composite parent) { Button button = new Button(parent, SWT.PUSH); PropsUi.setLook(button); - button.setImage(GuiResource.getInstance().getImageHelp()); button.setText(BaseMessages.getString(PKG, "System.Button.Help")); button.setToolTipText(BaseMessages.getString(PKG, "System.Tooltip.Help")); FormData fdButton = new FormData(); fdButton.left = new FormAttachment(0, 0); fdButton.bottom = new FormAttachment(100, 0); button.setLayoutData(fdButton); + applyHelpButtonImage(button); // Always available in read-only dialogs BaseDialog.keepEnabledInReadOnly(button); return button; } + /** + * Set the standard help icon on a push button. + * + *

Call after {@code setText} and after attaching {@link FormData}. On Hop Web, RAP sizes PUSH + * buttons to the zoomed bitmap plus theme padding, which would make Help taller than OK/Cancel. A + * font-sized bitmap, a compact {@code helpButton} variant, and a locked height keep the + * question-mark icon without changing the row height. Native SWT already fits {@link + * ConstUi#SMALL_ICON_SIZE} in platform chrome. + */ + public static void applyHelpButtonImage(Button button) { + if (button == null || button.isDisposed()) { + return; + } + if (!EnvironmentUtils.getInstance().isWeb()) { + button.setImage(GuiResource.getInstance().getImageHelp()); + return; + } + + int textHeight = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; + int request = webHelpIconRequestSize(PropsUi.getInstance().getZoomFactor()); + button.setImage(GuiResource.getInstance().getImage("ui/images/help.svg", request, request)); + button.setData(RAP_CUSTOM_VARIANT, HELP_BUTTON_VARIANT); + if (button.getLayoutData() instanceof FormData fd) { + fd.height = textHeight; + } + } + + /** + * Inverse of {@link GuiResource} zoom so the help bitmap is {@link ConstUi#SMALL_ICON_SIZE} px on + * Hop Web. + */ + static int webHelpIconRequestSize(double zoomFactor) { + if (zoomFactor <= 0) { + return ConstUi.SMALL_ICON_SIZE; + } + return Math.max(1, (int) Math.round(ConstUi.SMALL_ICON_SIZE / zoomFactor)); + } + public static boolean isPluginDocumented(IPlugin plugin) { if (plugin == null) { return false; diff --git a/ui/src/test/java/org/apache/hop/ui/util/HelpUtilsTest.java b/ui/src/test/java/org/apache/hop/ui/util/HelpUtilsTest.java index c175c67dd41..d2926c31752 100644 --- a/ui/src/test/java/org/apache/hop/ui/util/HelpUtilsTest.java +++ b/ui/src/test/java/org/apache/hop/ui/util/HelpUtilsTest.java @@ -21,8 +21,10 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.apache.hop.ui.core.ConstUi; import org.junit.jupiter.api.Test; +/** Unit test for {@link HelpUtils} */ class HelpUtilsTest { @Test @@ -46,4 +48,14 @@ void appendUtmParametersPassesThroughBlank() { assertEquals("", HelpUtils.appendUtmParameters("")); assertEquals(null, HelpUtils.appendUtmParameters(null)); } + + @Test + void webHelpIconRequestSizeCancelsDefaultWebZoom() { + // nativeZoomFactor on web is globalZoom / 0.75; at 100% that is 4/3 + assertEquals(12, HelpUtils.webHelpIconRequestSize(4.0 / 3.0)); + assertEquals(8, HelpUtils.webHelpIconRequestSize(2.0)); + assertEquals(ConstUi.SMALL_ICON_SIZE, HelpUtils.webHelpIconRequestSize(0)); + assertEquals(ConstUi.SMALL_ICON_SIZE, HelpUtils.webHelpIconRequestSize(-1)); + assertEquals(1, HelpUtils.webHelpIconRequestSize(100)); + } }