package name.abuchen.portfolio.ui; import java.util.Arrays; import java.util.Objects; import java.util.StringJoiner; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Sash; public class SashHelper { private final String identifier; private final IPreferenceStore preferences; private int[] defaultWidths; public SashHelper(String identifier, IPreferenceStore preferences) { this.identifier = identifier; this.preferences = preferences; load(); } public void setConstantWidth(int[] defaultWidths) { if (this.defaultWidths == null) this.defaultWidths = defaultWidths; } public void attachTo(SashForm sash) { Objects.requireNonNull(sash); sash.addListener(SWT.Resize, new Listener() { @Override public void handleEvent(Event event) { updateDefaultWeights(sash); applyWeights(sash); } }); sash.addDisposeListener(e -> save(sash)); applyWeights(sash); } private void load() { String config = preferences.getString(identifier); if (config != null) { try { String[] parts = config.split(","); //$NON-NLS-1$ int[] widths = Arrays.stream(parts).mapToInt(Integer::parseInt).toArray(); defaultWidths = widths; } catch (NumberFormatException ignore) { // ignore -> assign weight from scratch } } } private void save(SashForm sash) { updateDefaultWeights(sash); StringJoiner config = new StringJoiner(","); //$NON-NLS-1$ for (int w : defaultWidths) config.add(String.valueOf(w)); preferences.putValue(identifier, config.toString()); } private void updateDefaultWeights(SashForm sash) { Control[] children = sash.getChildren(); for (int ii = 0; ii < defaultWidths.length; ii++) { if (defaultWidths[ii] > 0 && ii < children.length) { int width = children[ii].getBounds().width; if (width > 0) defaultWidths[ii] = width; } } } private void applyWeights(SashForm sash) { int numOfChildren = (int) Arrays.stream(sash.getChildren()).filter(c -> !(c instanceof Sash)).count(); if (defaultWidths == null) defaultWidths = new int[numOfChildren]; int parentWidth = getParentWidth(sash); int[] weights = new int[numOfChildren]; int columnsWithoutWidth = 0; for (int ii = 0; ii < weights.length; ii++) { if (defaultWidths[ii] > 0) { weights[ii] = defaultWidths[ii]; parentWidth -= weights[ii]; } else { columnsWithoutWidth++; } } for (int ii = 0; ii < weights.length; ii++) { if (weights[ii] == 0) weights[ii] = parentWidth / columnsWithoutWidth; } sash.setWeights(weights); } private int getParentWidth(SashForm sash) { Composite parent = sash.getParent().getParent(); int parentWidth = parent.getBounds().width; if (parentWidth == 0) { // #pack is required if parent has never been rendered before parent.pack(); parentWidth = parent.getBounds().width; } parentWidth -= sash.getSashWidth(); return parentWidth; } }