/* * Copyright (c) 2015 the original author or authors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Etienne Studer & Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation */ package org.eclipse.buildship.ui.util.widget; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; /** * Creates SWT widgets and aligns them through a fluent API. * * All created controls are assumed to be part of a {@link org.eclipse.swt.layout.GridLayout}. * * @param <T> the type of the control to build */ public final class UiBuilder<T extends Control> { private final T control; private UiBuilder(T control) { this.control = Preconditions.checkNotNull(control); } public T control() { return this.control; } /** * Aligns the created widget to the left. * * @return the builder */ public UiBuilder<T> alignLeft() { this.control.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1)); return this; } /** * Aligns the created widget to fill the cell horizontally. * * @return the builder */ public UiBuilder<T> alignFillHorizontal() { this.control.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); return this; } /** * Aligns the created widget to fill both horizontal and vertical. * * @return the builder */ public UiBuilder<T> alignFillBoth(int horizontalSpan) { this.control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, horizontalSpan, 1)); return this; } /** * Enables the created widget. * * @return the builder */ public UiBuilder<T> enabled() { this.control.setEnabled(true); return this; } /** * Disables the created widget. * * @return the builder */ public UiBuilder<T> disabled() { this.control.setEnabled(false); return this; } /** * Sets the argument as the current widget's font. * * @param font the font to set on the widget * @return the builder */ public UiBuilder<T> font(Font font) { this.control.setFont(font); return this; } /** * Sets the argument as the current widget's text. * * @param text the text to set on the widget * @return the builder * @throws IllegalArgumentException thrown if the the control does not support the text property */ public UiBuilder<T> text(String text) { text = Strings.nullToEmpty(text); T control = control(); if (control instanceof Label) { ((Label) control).setText(text); } else if (control instanceof Text) { ((Text) control).setText(text); } else if (control instanceof Button) { ((Button) control).setText(text); } else if (control instanceof Combo) { ((Combo) control).setText(text); } else if (control instanceof Group) { ((Group)control).setText(text); } else { throw new IllegalStateException(String.format("Cannot set text on control of type %s.", control().getClass())); } return this; } /** * Factory for {@code UiBuilder} instances. */ public static final class UiBuilderFactory { private final Optional<Font> defaultFont; public UiBuilderFactory(Font font) { this.defaultFont = Optional.of(font); } /** * Creates a new {@link Label} control. * * @param parent the parent control * @return the builder */ public UiBuilder<Label> newLabel(Composite parent) { UiBuilder<Label> builder = new UiBuilder<Label>(new Label(parent, SWT.NONE)); init(builder); return builder; } /** * Creates a new {@link Text} control. * * @param parent the parent control * @return the builder */ public UiBuilder<Text> newText(Composite parent) { UiBuilder<Text> builder = new UiBuilder<Text>(new Text(parent, SWT.BORDER)); init(builder); return builder; } /** * Creates a new {@link Button} control. * * @param parent the parent control * @return the builder */ public UiBuilder<Button> newButton(Composite parent) { UiBuilder<Button> builder = new UiBuilder<Button>(new Button(parent, SWT.PUSH)); init(builder); return builder; } /** * Creates a new radio button which is a {@link Button} control with the {@link SWT#RADIO} * style bit specified. * * @param parent the parent control * @return the builder */ public UiBuilder<Button> newRadio(Composite parent) { UiBuilder<Button> builder = new UiBuilder<Button>(new Button(parent, SWT.RADIO)); init(builder); return builder; } /** * Creates a new checkbox which is a {@link Button} control with the {@link SWT#CHECK} * style bit specified. * * @param parent the parent control * @return the builder */ public UiBuilder<Button> newCheckbox(Composite parent) { UiBuilder<Button> builder = new UiBuilder<Button>(new Button(parent, SWT.CHECK)); init(builder); return builder; } /** * Creates a new {@link Combo} control. * * @param parent the parent control * @return the builder */ public UiBuilder<Combo> newCombo(Composite parent) { UiBuilder<Combo> builder = new UiBuilder<Combo>(new Combo(parent, SWT.NONE)); init(builder); return builder; } /** * Creates a new {@link Tree} control. * * @param parent The parent control of the result tree. * @return the builder */ public UiBuilder<Tree> newTree(Composite parent) { UiBuilder<Tree> builder = new UiBuilder<Tree>(new Tree(parent, SWT.NONE)); init(builder); return builder; } /** * Creates a new {@link Group} control. * * @param parent The parent control of the result group. * @return the builder */ public UiBuilder<Group> newGroup(Composite parent) { UiBuilder<Group> builder = new UiBuilder<Group>(new Group(parent, SWT.NONE)); init(builder); return builder; } /** * Fills the next cell in the gridlayout with nothing, i.e. with an empty button to enforce * a certain minimum row height. * * @param parent the control having the {@link org.eclipse.swt.layout.GridLayout} having the next column to be empty */ public void span(Composite parent) { Button b = new Button(parent, SWT.NONE); init(b); b.setVisible(false); } private void init(UiBuilder<?> builder) { init(builder.control()); } private void init(Control control) { if (this.defaultFont.isPresent()) { control.setFont(this.defaultFont.get()); } } } }