package com.kartoflane.superluminal2.ui.sidebar; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import com.kartoflane.superluminal2.Superluminal; import com.kartoflane.superluminal2.components.enums.OS; import com.kartoflane.superluminal2.core.Cache; import com.kartoflane.superluminal2.core.Manager; import com.kartoflane.superluminal2.mvc.controllers.AbstractController; import com.kartoflane.superluminal2.ui.EditorWindow; import com.kartoflane.superluminal2.ui.sidebar.data.DataComposite; import com.kartoflane.superluminal2.utils.UIUtils; import com.kartoflane.superluminal2.utils.Utils; public class ManipulationToolComposite extends Composite implements DataComposite { private Button btnPinned; private Composite boundsContainer; private Composite dataContainer; private AbstractController controller; private Button btnUp; private Button btnLeft; private Button btnRight; private Button btnDown; private Spinner spNudge; private Label lblX; private Spinner spX; private Label lblY; private Spinner spY; private boolean dataLoad = false; public ManipulationToolComposite(Composite parent, boolean location, boolean size) { super(parent, SWT.NONE); setLayout(new GridLayout(2, false)); Label label = new Label(this, SWT.NONE); label.setAlignment(SWT.CENTER); label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); label.setText("Manipulation Tool"); Image helpImage = Cache.checkOutImage(this, "cpath:/assets/help.png"); Label lblHelp = new Label(this, SWT.NONE); lblHelp.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblHelp.setImage(helpImage); String msg = "- Left-click on a highlighted object to select it.\n" + "- Left-click on empty space to deselect.\n" + "- Only one object can be selected at a time."; UIUtils.addTooltip(lblHelp, msg); Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1)); boundsContainer = new Composite(this, SWT.BORDER); GridLayout gl_boundsContainer = new GridLayout(3, false); boundsContainer.setLayout(gl_boundsContainer); boundsContainer.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1)); btnPinned = new Button(boundsContainer, SWT.CHECK); btnPinned.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 3, 1)); btnPinned.setText("Pinned"); lblX = new Label(boundsContainer, SWT.NONE); lblX.setText("X:"); spX = new Spinner(boundsContainer, SWT.BORDER); GridData gd_spX = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1); gd_spX.widthHint = 35; spX.setLayoutData(gd_spX); spX.setEnabled(false); spX.setTextLimit(4); spX.setMaximum(9999); spX.setMinimum(-999); lblY = new Label(boundsContainer, SWT.NONE); lblY.setText("Y:"); spY = new Spinner(boundsContainer, SWT.BORDER); GridData gd_spY = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1); gd_spY.widthHint = 35; spY.setLayoutData(gd_spY); spY.setEnabled(false); spY.setTextLimit(4); spY.setMaximum(9999); spY.setMinimum(-999); btnUp = new Button(boundsContainer, SWT.NONE); btnUp.setImage(Cache.checkOutImage(this, "cpath:/assets/up.png")); GridData gd_btnUp = new GridData(SWT.CENTER, SWT.CENTER, true, false, 3, 1); gd_btnUp.heightHint = 36; gd_btnUp.widthHint = 36; btnUp.setLayoutData(gd_btnUp); btnLeft = new Button(boundsContainer, SWT.NONE); btnLeft.setImage(Cache.checkOutImage(this, "cpath:/assets/left.png")); GridData gd_btnLeft = new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1); gd_btnLeft.heightHint = 36; gd_btnLeft.widthHint = 36; btnLeft.setLayoutData(gd_btnLeft); spNudge = new Spinner(boundsContainer, SWT.BORDER); GridData gd_spNudge = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1); gd_spNudge.widthHint = 20; spNudge.setLayoutData(gd_spNudge); spNudge.setMinimum(1); msg = "This determines how much the selected object\nwill move when you press the arrows."; UIUtils.addTooltip(spNudge, Utils.wrapOSNot(msg, Superluminal.WRAP_WIDTH, Superluminal.WRAP_TOLERANCE, OS.MACOSX())); btnRight = new Button(boundsContainer, SWT.NONE); btnRight.setImage(Cache.checkOutImage(this, "cpath:/assets/right.png")); GridData gd_btnRight = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); gd_btnRight.widthHint = 36; gd_btnRight.heightHint = 36; btnRight.setLayoutData(gd_btnRight); btnDown = new Button(boundsContainer, SWT.NONE); btnDown.setImage(Cache.checkOutImage(this, "cpath:/assets/down.png")); GridData gd_btnDown = new GridData(SWT.CENTER, SWT.CENTER, false, false, 3, 1); gd_btnDown.widthHint = 36; gd_btnDown.heightHint = 36; btnDown.setLayoutData(gd_btnDown); dataContainer = new Composite(this, SWT.BORDER); dataContainer.setLayout(new FillLayout(SWT.HORIZONTAL)); dataContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); btnPinned.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { controller.setPinned(btnPinned.getSelection()); setController(controller); EditorWindow.getInstance().forceFocus(); } }); btnUp.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Rectangle oldBounds = controller.getBounds(); Point p = controller.getPresentedLocation(); controller.setPresentedLocation(p.x, p.y - spNudge.getSelection()); updateController(); updateData(); EditorWindow.getInstance().canvasRedraw(oldBounds); EditorWindow.getInstance().forceFocus(); } }); btnDown.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Rectangle oldBounds = controller.getBounds(); Point p = controller.getPresentedLocation(); controller.setPresentedLocation(p.x, p.y + spNudge.getSelection()); updateController(); updateData(); EditorWindow.getInstance().canvasRedraw(oldBounds); EditorWindow.getInstance().forceFocus(); } }); btnLeft.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Rectangle oldBounds = controller.getBounds(); Point p = controller.getPresentedLocation(); controller.setPresentedLocation(p.x - spNudge.getSelection(), p.y); updateController(); updateData(); EditorWindow.getInstance().canvasRedraw(oldBounds); EditorWindow.getInstance().forceFocus(); } }); btnRight.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Rectangle oldBounds = controller.getBounds(); Point p = controller.getPresentedLocation(); controller.setPresentedLocation(p.x + spNudge.getSelection(), p.y); updateController(); updateData(); EditorWindow.getInstance().canvasRedraw(oldBounds); EditorWindow.getInstance().forceFocus(); } }); ModifyListener applyLocListener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (!dataLoad) applyLocation(); } }; spX.addModifyListener(applyLocListener); spY.addModifyListener(applyLocListener); setEnabled(false); } private void updateController() { controller.updateFollowOffset(); Manager.getCurrentShip().updateBoundingArea(); controller.updateView(); controller.redraw(); } public void setController(AbstractController controller) { dataLoad = true; if (controller != null) { if (this.controller != null && this.controller.getClass().equals(controller.getClass())) { // If the previously selected object is of the same type as the newly // selected one, don't dispose the composite -- just update it with new data DataComposite dc = getDataComposite(); dc.setController(controller); dc.updateData(); } else { // If they are of different types, or no object was previously selected, // create a new composite and insert it into the data container Composite c = (Composite) getDataComposite(); if (c != null) c.dispose(); c = (Composite) controller.getDataComposite(dataContainer); if (c != null) { Control[] changed = { c }; dataContainer.layout(changed); } } } dataLoad = false; this.controller = controller; reloadController(); } public void reloadController() { dataLoad = true; if (controller == null) { btnPinned.setSelection(false); Composite c = (Composite) getDataComposite(); if (c != null) c.dispose(); spX.setSelection(0); spY.setSelection(0); spNudge.setSelection(1); setEnabled(false); } else { setEnabled(true); btnPinned.setSelection(controller.isPinned()); spX.setEnabled(!controller.isPinned() && controller.isLocModifiable()); spY.setEnabled(!controller.isPinned() && controller.isLocModifiable()); btnUp.setEnabled(!controller.isPinned() && controller.isLocModifiable()); btnLeft.setEnabled(!controller.isPinned() && controller.isLocModifiable()); btnDown.setEnabled(!controller.isPinned() && controller.isLocModifiable()); btnRight.setEnabled(!controller.isPinned() && controller.isLocModifiable()); spNudge.setEnabled(!controller.isPinned() && controller.isLocModifiable()); DataComposite dc = getDataComposite(); dc.setController(controller); dc.updateData(); } dataLoad = false; updateData(); EditorWindow.getInstance().updateSidebarScroll(); } private DataComposite getDataComposite() { if (dataContainer.getChildren().length == 0) return null; else return (DataComposite) dataContainer.getChildren()[0]; } public void updateData() { if (controller == null) return; dataLoad = true; Point p = controller.getPresentedLocation(); spX.setSelection(p.x); spY.setSelection(p.y); if (getDataComposite() != null) getDataComposite().updateData(); dataLoad = false; } @Override public void setEnabled(boolean enable) { btnPinned.setEnabled(enable); spX.setEnabled(enable); spY.setEnabled(enable); btnUp.setEnabled(enable); btnLeft.setEnabled(enable); btnDown.setEnabled(enable); btnRight.setEnabled(enable); spNudge.setEnabled(enable); } private void applyLocation() { if (controller != null && controller.isLocModifiable()) { Rectangle oldBounds = controller.getBounds(); controller.setPresentedLocation(spX.getSelection(), spY.getSelection()); controller.updateFollowOffset(); controller.updateView(); Manager.getCurrentShip().updateBoundingArea(); controller.redraw(); AbstractController.redraw(oldBounds); } } @Override public boolean isFocusControl() { Control c = UIUtils.getDisplay().getFocusControl(); return c == btnPinned || c == spNudge || c == spX || c == spY; } @Override public void dispose() { super.dispose(); Cache.checkInImage(this, "cpath:/assets/help.png"); } }