diff --git a/src/com/maccasoft/tools/Application.java b/src/com/maccasoft/tools/Application.java index 1495c8c..ef030d2 100644 --- a/src/com/maccasoft/tools/Application.java +++ b/src/com/maccasoft/tools/Application.java @@ -32,6 +32,10 @@ import java.util.Iterator; import java.util.List; import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.core.databinding.observable.value.IValueChangeListener; +import org.eclipse.core.databinding.observable.value.ValueChangeEvent; +import org.eclipse.core.databinding.observable.value.WritableValue; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.databinding.swt.DisplayRealm; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; @@ -43,6 +47,8 @@ import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabFolder2Adapter; import org.eclipse.swt.custom.CTabFolderEvent; import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.custom.CaretEvent; +import org.eclipse.swt.custom.CaretListener; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.DisposeEvent; @@ -91,11 +97,26 @@ public class Application { SashForm sashForm2; CTabFolder tabFolder; Console console; + StatusLine statusLine; SerialTerminal terminal; Preferences preferences; + WritableValue tabFolderSelection; + + final CaretListener caretListener = new CaretListener() { + + @Override + public void caretMoved(CaretEvent event) { + StyledText text = (StyledText) event.widget; + int offset = text.getCaretOffset(); + int y = text.getLineAtOffset(offset); + int x = offset - text.getOffsetAtLine(y); + statusLine.setCaretPosition(String.format("%d : %d ", y + 1, x + 1)); + } + }; + public Application() { preferences = Preferences.getInstance(); } @@ -145,6 +166,9 @@ public class Application { control = createContents(shell); control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + statusLine = new StatusLine(shell); + statusLine.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + shell.open(); shell.addListener(SWT.Close, new Listener() { @@ -638,15 +662,17 @@ public class Application { sashForm2 = new SashForm(sashForm1, SWT.VERTICAL); sashForm2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - tabFolder = new CTabFolder(sashForm2, SWT.BORDER); - tabFolder.setTabHeight((int) (fontMetrics.getHeight() * 1.5)); - tabFolder.addSelectionListener(new SelectionAdapter() { + tabFolder = new CTabFolder(sashForm2, SWT.BORDER) { @Override - public void widgetSelected(SelectionEvent e) { - + public void setSelection(int index) { + super.setSelection(index); + CTabItem tabItem = tabFolder.getSelection(); + tabFolderSelection.setValue(tabItem != null ? tabItem.getData() : null); } - }); + + }; + tabFolder.setTabHeight((int) (fontMetrics.getHeight() * 1.5)); tabFolder.addCTabFolder2Listener(new CTabFolder2Adapter() { @Override @@ -656,6 +682,30 @@ public class Application { } }); + tabFolderSelection = new WritableValue(); + tabFolderSelection.addValueChangeListener(new IValueChangeListener() { + + @Override + public void handleValueChange(ValueChangeEvent event) { + SourceEditorTab tab = (SourceEditorTab) event.diff.getOldValue(); + if (tab != null) { + tab.getEditor().removeCaretListener(caretListener); + } + tab = (SourceEditorTab) event.diff.getNewValue(); + if (tab != null) { + StyledText text = tab.getEditor().getStyledText(); + int offset = text.getCaretOffset(); + int y = text.getLineAtOffset(offset); + int x = offset - text.getOffsetAtLine(y); + statusLine.setCaretPosition(String.format("%d : %d ", y + 1, x + 1)); + tab.getEditor().addCaretListener(caretListener); + } + else { + statusLine.setCaretPosition(""); + } + } + }); + console = new Console(sashForm2); console.getStyledText().addListener(SWT.MouseDown, new Listener() { @@ -1040,7 +1090,12 @@ public class Application { @Override public void run() { + IProgressMonitor monitor = statusLine.getProgressMonitor(); + monitor.beginTask("Compile", IProgressMonitor.UNKNOWN); + compile(builder, reader, name, file); + + monitor.done(); } }).start(); } @@ -1289,6 +1344,9 @@ public class Application { @Override public void run() { + IProgressMonitor monitor = statusLine.getProgressMonitor(); + monitor.beginTask("Compile", IProgressMonitor.UNKNOWN); + try { Source source = compile(builder, reader, name, file); if (source == null) { @@ -1304,18 +1362,25 @@ public class Application { }); SerialPort serialPort = terminal.getSerialPort(); + StringBuilder sb = buildIntelHexString(new ArrayList(source.getLines())); + monitor.beginTask("Upload", sb.length()); out.println("Sending to serial port " + serialPort.getPortName() + " ..."); - StringBuilder sb = buildIntelHexString(new ArrayList(source.getLines())); for (int i = 0; i < sb.length(); i++) { serialPort.writeInt(sb.charAt(i)); + monitor.worked(1); } + while (serialPort.getOutputBufferBytesCount() > 0) { + Thread.sleep(1); + } + } catch (Exception e) { e.printStackTrace(); } out.println("Done"); + monitor.done(); } }).start(); diff --git a/src/com/maccasoft/tools/StatusLine.java b/src/com/maccasoft/tools/StatusLine.java new file mode 100644 index 0000000..11c862a --- /dev/null +++ b/src/com/maccasoft/tools/StatusLine.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2018 Marco Maccaferri and others. + * 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 + */ + +package com.maccasoft.tools; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ProgressIndicator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; + +public class StatusLine implements IProgressMonitor { + + Display display; + Composite container; + + Label messageLabel; + Label caretPositionLabel; + ProgressIndicator progressBar; + + public StatusLine(Composite parent) { + display = parent.getDisplay(); + + container = new Composite(parent, SWT.NONE); + + GC gc = new GC(parent); + FontMetrics fontMetrics = gc.getFontMetrics(); + gc.dispose(); + + messageLabel = new Label(container, SWT.NONE); + messageLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + addSeparator(); + + caretPositionLabel = new Label(container, SWT.CENTER); + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false); + layoutData.widthHint = Dialog.convertWidthInCharsToPixels(fontMetrics, 10); + caretPositionLabel.setLayoutData(layoutData); + + addSeparator(); + + Label label = new Label(container, SWT.NONE); + layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false); + layoutData.widthHint = Dialog.convertWidthInCharsToPixels(fontMetrics, 35); + label.setLayoutData(layoutData); + + addSeparator(); + + progressBar = new ProgressIndicator(container, SWT.HORIZONTAL); + layoutData = new GridData(GridData.GRAB_VERTICAL); + layoutData.widthHint = 128; + progressBar.setLayoutData(layoutData); + + GridLayout layout = new GridLayout(container.getChildren().length, false); + layout.marginHeight = 0; + container.setLayout(layout); + } + + void addSeparator() { + Label label = new Label(container, SWT.SEPARATOR); + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, false, true); + layoutData.heightHint = 24; + label.setLayoutData(layoutData); + } + + public void setLayoutData(Object data) { + container.setLayoutData(data); + } + + public Object getLayoutData() { + return container.getLayoutData(); + } + + public void setMessage(String text) { + messageLabel.setText(text); + } + + public void setCaretPosition(String text) { + caretPositionLabel.setText(text); + } + + public IProgressMonitor getProgressMonitor() { + return this; + } + + @Override + public void beginTask(String name, final int totalWork) { + final boolean animated = (totalWork == UNKNOWN || totalWork == 0); + display.syncExec(new Runnable() { + + @Override + public void run() { + if (progressBar == null || progressBar.isDisposed()) { + return; + } + + if (!progressBar.getVisible()) { + progressBar.setVisible(true); + container.layout(); + } + if (!animated) { + progressBar.beginTask(totalWork); + } + else { + progressBar.beginAnimatedTask(); + } + } + }); + } + + @Override + public void done() { + display.syncExec(new Runnable() { + + @Override + public void run() { + if (progressBar == null || progressBar.isDisposed()) { + return; + } + progressBar.sendRemainingWork(); + progressBar.done(); + } + }); + } + + @Override + public void subTask(String name) { + + } + + @Override + public void worked(int work) { + internalWorked(work); + } + + @Override + public void internalWorked(final double work) { + display.syncExec(new Runnable() { + + @Override + public void run() { + if (progressBar == null || progressBar.isDisposed()) { + return; + } + progressBar.worked(work); + } + }); + } + + @Override + public boolean isCanceled() { + return false; + } + + @Override + public void setCanceled(boolean value) { + + } + + @Override + public void setTaskName(String name) { + + } +}