This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 1497aece5e Fix execution results Logging toolbar spacing and top-right
button alignment (#8140)
1497aece5e is described below
commit 1497aece5eab7b26b9b2348e1eafe34e4caf991b
Author: Lance <[email protected]>
AuthorDate: Fri Aug 28 22:10:02 2026 +0800
Fix execution results Logging toolbar spacing and top-right button
alignment (#8140)
Signed-off-by: lance <[email protected]>
---
.../java/org/apache/hop/ui/core/WidgetUtils.java | 69 ++++++++++++++++++++++
.../apache/hop/ui/core/gui/GuiToolbarWidgets.java | 31 ++++++++--
.../hopgui/file/pipeline/HopGuiPipelineGraph.java | 6 +-
.../hopgui/file/workflow/HopGuiWorkflowGraph.java | 6 +-
4 files changed, 98 insertions(+), 14 deletions(-)
diff --git a/ui/src/main/java/org/apache/hop/ui/core/WidgetUtils.java
b/ui/src/main/java/org/apache/hop/ui/core/WidgetUtils.java
index 134492bf9b..94ff35e277 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/WidgetUtils.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/WidgetUtils.java
@@ -30,14 +30,18 @@ import org.apache.hop.ui.core.widget.ComboVar;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ToolBar;
public abstract class WidgetUtils {
+ private static final String TOP_RIGHT_ALIGNING = "hop.alignTopRight";
+
private WidgetUtils() {}
public static void setFormLayout(Composite composite, int margin) {
@@ -136,4 +140,69 @@ public abstract class WidgetUtils {
public static FormData secondColumn(Control top) {
return new FormDataBuilder().top(top,
ConstUi.MEDIUM_MARGIN).right().left(53, 0).result();
}
+
+ /**
+ * Create a flat toolbar for {@link CTabFolder#setTopRight(Control, int)}
that stays vertically
+ * centered in the tab header.
+ *
+ * <p>{@code CTabFolder} only centers top-right controls when tab height is
left at the default.
+ * Hop sets a fixed height ({@code setTabHeight(28)}), and in that mode the
folder pins the
+ * control to {@code y = 1}. This method listens for that layout and moves
the toolbar to the
+ * vertical center of the tab strip.
+ *
+ * @param tabFolder the folder that hosts the toolbar
+ * @return the toolbar to add items to; call {@link
CTabFolder#setTabHeight(int)} after adding
+ * items so the header is at least as tall as the toolbar
+ */
+ public static ToolBar createCenteredTopRightToolBar(CTabFolder tabFolder) {
+ ToolBar toolBar = new ToolBar(tabFolder, SWT.FLAT);
+ PropsUi.setLook(toolBar);
+ toolBar.setBackground(tabFolder.getBackground());
+ tabFolder.setTopRight(toolBar, SWT.RIGHT);
+
+ Listener align = e -> alignTopRightInTabHeader(tabFolder, toolBar);
+ tabFolder.addListener(SWT.Resize, align);
+ toolBar.addListener(SWT.Move, align);
+ return toolBar;
+ }
+
+ private static void alignTopRightInTabHeader(CTabFolder tabFolder, Control
control) {
+ if (tabFolder.isDisposed() || control.isDisposed()) {
+ return;
+ }
+ if (Boolean.TRUE.equals(control.getData(TOP_RIGHT_ALIGNING))) {
+ return;
+ }
+
+ Rectangle bounds = control.getBounds();
+ if (bounds.width <= 0 || bounds.height <= 0) {
+ return;
+ }
+
+ int headerY = 0;
+ int headerHeight = tabFolder.getTabHeight();
+ if (tabFolder.getItemCount() > 0) {
+ Rectangle tab = tabFolder.getItem(0).getBounds();
+ if (tab.height > 0) {
+ headerY = tab.y;
+ headerHeight = tab.height;
+ }
+ }
+
+ // Windows ToolBar preferred height includes empty space below the 16px
icons. Center on
+ // the icon row so the buttons line up with the tab text instead of
sitting on the top edge.
+ int iconHeight = (int) Math.round(ConstUi.SMALL_ICON_SIZE *
PropsUi.getNativeZoomFactor()) + 4;
+ int contentHeight = Math.min(bounds.height, iconHeight);
+ int y = headerY + Math.max(0, (headerHeight - contentHeight) / 2);
+ if (bounds.y == y) {
+ return;
+ }
+
+ control.setData(TOP_RIGHT_ALIGNING, Boolean.TRUE);
+ try {
+ control.setLocation(bounds.x, y);
+ } finally {
+ control.setData(TOP_RIGHT_ALIGNING, Boolean.FALSE);
+ }
+ }
}
diff --git a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
index 4508c9b53d..e2715de600 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
@@ -265,6 +265,8 @@ public class GuiToolbarWidgets extends BaseGuiWidgets
implements IToolbarWidgetR
break;
case TEXT:
addWebToolbarText(toolbarItem, parent);
+ addWebToolbarGap(parent);
+ break;
default:
break;
}
@@ -354,6 +356,12 @@ public class GuiToolbarWidgets extends BaseGuiWidgets
implements IToolbarWidgetR
widgetsMap.put(toolbarItem.getId(), text);
}
+ private void addWebToolbarGap(Composite parent) {
+ Label spacer = new Label(parent, SWT.NONE);
+ PropsUi.setLook(spacer, Props.WIDGET_STYLE_TOOLBAR);
+ spacer.setLayoutData(new RowData(PropsUi.getMargin() * 2, 1));
+ }
+
/**
* Fire the toolbar action when the user presses Enter in a single-line text
field. Needed because
* {@link SWT#DefaultSelection} is not consistently delivered for Text
widgets embedded in a
@@ -521,9 +529,19 @@ public class GuiToolbarWidgets extends BaseGuiWidgets
implements IToolbarWidgetR
private void addToolbarText(GuiToolbarItem toolbarItem, ToolBar toolBar) {
ToolItem textSeparator = new ToolItem(toolBar, SWT.SEPARATOR | SWT.BOTTOM);
+ int gap = PropsUi.getMargin() * 2;
+
+ Composite wrapper = new Composite(toolBar, SWT.NONE);
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.marginRight = gap;
+ wrapper.setLayout(layout);
+ PropsUi.setLook(wrapper, Props.WIDGET_STYLE_TOOLBAR);
+
Text text =
new Text(
- toolBar,
+ wrapper,
SWT.SINGLE
| SWT.BORDER
| (toolbarItem.isAlignRight() ? SWT.RIGHT : SWT.LEFT)
@@ -531,10 +549,7 @@ public class GuiToolbarWidgets extends BaseGuiWidgets
implements IToolbarWidgetR
text.setText(Const.NVL(toolbarItem.getDefaultText(), ""));
text.setToolTipText(Const.NVL(toolbarItem.getToolTip(), ""));
PropsUi.setLook(text, Props.WIDGET_STYLE_TOOLBAR);
- text.pack();
- // extra room for widget decorations
- textSeparator.setWidth(200 + toolbarItem.getExtraWidth());
- textSeparator.setControl(text);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Listener listener = getListener(toolbarItem);
text.addListener(SWT.Selection, listener);
@@ -543,9 +558,13 @@ public class GuiToolbarWidgets extends BaseGuiWidgets
implements IToolbarWidgetR
// SEPARATOR. Explicit CR / KEYPAD_CR ensures Enter applies the filter
(e.g. Execution
// perspective).
addTextEnterKeyListener(text, listener);
+
+ // Extra width is the input size; gap keeps the next item (often
Highlight) from sitting flush
+ // against the field. widgetsMap still stores the Text so callers can read
it directly.
+ textSeparator.setWidth(200 + toolbarItem.getExtraWidth() + gap);
+ textSeparator.setControl(wrapper);
toolItemMap.put(toolbarItem.getId(), textSeparator);
widgetsMap.put(toolbarItem.getId(), text);
- PropsUi.setLook(text, Props.WIDGET_STYLE_TOOLBAR);
}
private void addToolbarCheckbox(GuiToolbarItem toolbarItem, ToolBar toolBar)
{
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
index 303bb87d31..9185370722 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
@@ -139,6 +139,7 @@ import org.apache.hop.pipeline.transform.stream.Stream;
import org.apache.hop.pipeline.transform.stream.StreamIcon;
import org.apache.hop.ui.core.ConstUi;
import org.apache.hop.ui.core.PropsUi;
+import org.apache.hop.ui.core.WidgetUtils;
import org.apache.hop.ui.core.bus.HopGuiEvents;
import org.apache.hop.ui.core.dialog.BaseDialog;
import org.apache.hop.ui.core.dialog.ContextDialog;
@@ -5548,10 +5549,7 @@ public class HopGuiPipelineGraph extends
HopGuiAbstractGraph
}
// Create toolbar for the panel controls in the upper right corner...
- //
- ToolBar extraViewToolBar = new ToolBar(extraViewTabFolder, SWT.FLAT);
- extraViewTabFolder.setTopRight(extraViewToolBar, SWT.RIGHT);
- PropsUi.setLook(extraViewToolBar);
+ ToolBar extraViewToolBar =
WidgetUtils.createCenteredTopRightToolBar(extraViewTabFolder);
if (detached) {
ToolItem dockItem = new ToolItem(extraViewToolBar, SWT.PUSH);
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
index 5c3666f22c..f3292ae794 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
@@ -103,6 +103,7 @@ import
org.apache.hop.metadata.serializer.multi.MultiMetadataProvider;
import org.apache.hop.pipeline.PipelinePainter;
import org.apache.hop.ui.core.ConstUi;
import org.apache.hop.ui.core.PropsUi;
+import org.apache.hop.ui.core.WidgetUtils;
import org.apache.hop.ui.core.bus.HopGuiEvents;
import org.apache.hop.ui.core.dialog.BaseDialog;
import org.apache.hop.ui.core.dialog.ContextDialog;
@@ -4786,10 +4787,7 @@ public class HopGuiWorkflowGraph extends
HopGuiAbstractGraph
}
// Create toolbar for the panel controls in the upper right corner...
- //
- ToolBar extraViewToolBar = new ToolBar(extraViewTabFolder, SWT.FLAT);
- extraViewTabFolder.setTopRight(extraViewToolBar, SWT.RIGHT);
- PropsUi.setLook(extraViewToolBar);
+ ToolBar extraViewToolBar =
WidgetUtils.createCenteredTopRightToolBar(extraViewTabFolder);
if (detached) {
ToolItem dockItem = new ToolItem(extraViewToolBar, SWT.PUSH);