blob: 9a7115c4782b8305b15fed9cdc8dbb4579295c9b [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ecommons.ui.actions;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.ecommons.ui.components.SearchText;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
@NonNullByDefault
public class SearchContributionItem extends ContributionItem {
public static final int VIEW_TOOLBAR= 0x10000000;
private class SWTListener implements Listener {
@Override
public void handleEvent(final Event event) {
switch (event.type) {
case SWT.Resize:
scheduleSizeCheck();
return;
}
}
}
private final int options;
private SearchText control= nonNullLateInit();
private ToolItem textItem= nonNullLateInit();
private @Nullable String toolTipText;
private @Nullable Composite sizeControl;
private @Nullable Control resultControl;
private final boolean updateWhenTyping;
private final Runnable sizeCheckRunnable= new Runnable() {
@Override
public void run() {
SearchContributionItem.this.sizeCheckScheduled= false;
resize();
}
};
private boolean sizeCheckScheduled;
public SearchContributionItem(final String id, final int options,
final boolean updateWhenTyping) {
super(id);
this.options= options;
this.updateWhenTyping= updateWhenTyping;
}
public SearchContributionItem(final String id, final int options) {
this(id, options, false);
}
public SearchText getSearchText() {
return this.control;
}
/**
* Table or tree to select
*/
public void setResultControl(final @Nullable Control control) {
this.resultControl= control;
}
public void setToolTip(final @Nullable String text) {
this.toolTipText= text;
}
/**
* For views the control of the view
*/
public void setSizeControl(final Composite control) {
this.sizeControl= control;
control.addListener(SWT.Resize, new Listener() {
@Override
public void handleEvent(final Event event) {
resize();
}
});
}
public void resize() {
final var sizeControl= this.sizeControl;
if (this.textItem != null && !this.textItem.isDisposed()
&& sizeControl != null ) {
final int viewWidth= sizeControl.getClientArea().width;
if (viewWidth <= 0) {
return;
}
final ToolBar toolBar= this.textItem.getParent();
final Composite toolBarParent= nonNullAssert(toolBar.getParent());
final int toolBarWidth= toolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
final int currentWidth= this.textItem.getWidth();
final int minWidth= LayoutUtils.hintWidth(this.control.getTextControl(), 8);
int corr= toolBarWidth - currentWidth;
if ((this.options & VIEW_TOOLBAR) != 0) {
// E-4.2 View Toolbar (=> space for view menu)
final Layout layout= toolBarParent.getLayout();
if (layout instanceof RowLayout && ((RowLayout)layout).type == SWT.HORIZONTAL) {
final Control[] children= toolBarParent.getChildren();
for (int i= 0; i < children.length; i++) {
if (children[i] != toolBar) {
corr += children[i].getSize().x;
}
}
corr += (children.length - 1) * ((RowLayout)layout).spacing;
}
}
corr += 16; // 2 required
final int width= Math.min(310, Math.max(minWidth, viewWidth - corr));
if (width == currentWidth) {
return;
}
// scheduleSizeCheck();
this.textItem.setWidth(width);
toolBarParent.layout(new @NonNull Control[] { this.control });
toolBarParent.pack(true);
}
}
private void scheduleSizeCheck() {
if (!this.sizeCheckScheduled
&& this.textItem != null && !this.textItem.isDisposed() ) {
this.sizeCheckScheduled= true;
this.textItem.getDisplay().asyncExec(this.sizeCheckRunnable);
}
}
@Override
public void fill(final ToolBar parent, final int index) {
this.control= new SearchText(parent);
this.control.addListener(createSearchTextListener());
final Listener swtListener= new SWTListener();
this.control.addListener(SWT.Resize, swtListener);
this.control.setToolTipText(this.toolTipText);
this.textItem= new ToolItem(parent, SWT.SEPARATOR, index);
this.textItem.setControl(this.control);
this.textItem.setToolTipText(this.toolTipText);
this.textItem.setWidth(310); // high value prevents that the toolbar is moved to tabs
}
public Control create(final Composite parent) {
this.control= new SearchText(parent);
this.control.addListener(createSearchTextListener());
final Listener swtListener= new SWTListener();
this.control.addListener(SWT.Resize, swtListener);
this.control.setToolTipText(this.toolTipText);
return this.control;
}
protected SearchText.Listener createSearchTextListener() {
return new SearchText.Listener() {
@Override
public void textChanged(final boolean user) {
if (SearchContributionItem.this.updateWhenTyping || !user) {
SearchContributionItem.this.search();
}
}
@Override
public void okPressed() {
SearchContributionItem.this.search();
}
@Override
public void downPressed() {
SearchContributionItem.this.selectFirst();
}
};
}
protected void search() {
}
protected void selectFirst() {
final var resultControl= this.resultControl;
if (resultControl instanceof Table) {
final Table table= (Table)resultControl;
table.setFocus();
if (table.getSelectionCount() == 0) {
final int idx= table.getTopIndex();
if (idx >= 0) {
table.setSelection(idx);
}
}
}
else if (resultControl instanceof Tree) {
final Tree table= (Tree)resultControl;
table.setFocus();
if (table.getSelectionCount() == 0) {
final TreeItem item= table.getTopItem();
if (item != null) {
table.setSelection(item);
}
}
}
}
public String getText() {
return this.control.getText();
}
public void show() {
if (!UIAccess.isOkToUse(this.control)) {
return;
}
this.control.setFocus();
}
}