mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 06:49:36 -04:00
first working tutorial
This commit is contained in:
parent
8b5fe67016
commit
376a7259be
@ -452,7 +452,7 @@ public final class Keys {
|
|||||||
* enables the grid
|
* enables the grid
|
||||||
*/
|
*/
|
||||||
public static final Key<Boolean> SETTINGS_GRID
|
public static final Key<Boolean> SETTINGS_GRID
|
||||||
= new Key<>("grid", false);
|
= new Key<>("grid", true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enables the wire bits view
|
* enables the wire bits view
|
||||||
@ -786,6 +786,14 @@ public final class Keys {
|
|||||||
* Circuit is generic
|
* Circuit is generic
|
||||||
*/
|
*/
|
||||||
public static final Key<Boolean> IS_GENERIC =
|
public static final Key<Boolean> IS_GENERIC =
|
||||||
new Key<Boolean>("isGeneric", false).setSecondary();
|
new Key<>("isGeneric", false).setSecondary();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the tutorial
|
||||||
|
*/
|
||||||
|
public static final Key<Boolean> SETTINGS_SHOW_TUTORIAL =
|
||||||
|
new Key<>("showTutorial", true).setSecondary();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ import de.neemann.digital.gui.components.testing.TestAllDialog;
|
|||||||
import de.neemann.digital.gui.components.testing.ValueTableDialog;
|
import de.neemann.digital.gui.components.testing.ValueTableDialog;
|
||||||
import de.neemann.digital.gui.components.tree.LibraryTreeModel;
|
import de.neemann.digital.gui.components.tree.LibraryTreeModel;
|
||||||
import de.neemann.digital.gui.components.tree.SelectTree;
|
import de.neemann.digital.gui.components.tree.SelectTree;
|
||||||
|
import de.neemann.digital.gui.tutorial.InitialTutorial;
|
||||||
import de.neemann.digital.gui.release.CheckForNewRelease;
|
import de.neemann.digital.gui.release.CheckForNewRelease;
|
||||||
import de.neemann.digital.gui.remote.DigitalHandler;
|
import de.neemann.digital.gui.remote.DigitalHandler;
|
||||||
import de.neemann.digital.gui.remote.RemoteException;
|
import de.neemann.digital.gui.remote.RemoteException;
|
||||||
@ -1837,6 +1838,9 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
|||||||
}
|
}
|
||||||
main.setVisible(true);
|
main.setVisible(true);
|
||||||
|
|
||||||
|
if (Settings.getInstance().getAttributes().get(Keys.SETTINGS_SHOW_TUTORIAL))
|
||||||
|
new InitialTutorial(main).setVisible(true);
|
||||||
|
|
||||||
CheckForNewRelease.showReleaseDialog(main);
|
CheckForNewRelease.showReleaseDialog(main);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ public final class Settings implements AttributeListener {
|
|||||||
intList.add(Keys.SETTINGS_TOOLCHAIN_CONFIG);
|
intList.add(Keys.SETTINGS_TOOLCHAIN_CONFIG);
|
||||||
intList.add(Keys.SETTINGS_FONT_SCALING);
|
intList.add(Keys.SETTINGS_FONT_SCALING);
|
||||||
intList.add(Keys.SETTINGS_MAC_MOUSE);
|
intList.add(Keys.SETTINGS_MAC_MOUSE);
|
||||||
|
intList.add(Keys.SETTINGS_SHOW_TUTORIAL);
|
||||||
|
|
||||||
settingsKeys = Collections.unmodifiableList(intList);
|
settingsKeys = Collections.unmodifiableList(intList);
|
||||||
|
|
||||||
|
@ -133,6 +133,7 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
|||||||
private Mouse mouse = Mouse.getMouse();
|
private Mouse mouse = Mouse.getMouse();
|
||||||
private Circuit shallowCopy;
|
private Circuit shallowCopy;
|
||||||
private CircuitScrollPanel circuitScrollPanel;
|
private CircuitScrollPanel circuitScrollPanel;
|
||||||
|
private ModificationListener modificationListener;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -429,6 +430,8 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
|||||||
try {
|
try {
|
||||||
if (modification != null) {
|
if (modification != null) {
|
||||||
undoManager.apply(modification);
|
undoManager.apply(modification);
|
||||||
|
if (modificationListener != null)
|
||||||
|
modificationListener.modified(modification);
|
||||||
if (circuitScrollPanel != null)
|
if (circuitScrollPanel != null)
|
||||||
circuitScrollPanel.sizeChanged();
|
circuitScrollPanel.sizeChanged();
|
||||||
}
|
}
|
||||||
@ -620,6 +623,16 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
|||||||
getCircuit().clearState();
|
getCircuit().clearState();
|
||||||
}
|
}
|
||||||
requestFocusInWindow();
|
requestFocusInWindow();
|
||||||
|
|
||||||
|
if (modificationListener != null)
|
||||||
|
modificationListener.modified(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if circuit is running
|
||||||
|
*/
|
||||||
|
public boolean isRunning() {
|
||||||
|
return activeMouseController == mouseRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2314,6 +2327,15 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
|||||||
new MouseControllerWizard(wizardNotification).activate();
|
new MouseControllerWizard(wizardNotification).activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the modification listener.
|
||||||
|
*
|
||||||
|
* @param modificationListener is called every time the circuit is modified
|
||||||
|
*/
|
||||||
|
public void setModificationListener(ModificationListener modificationListener) {
|
||||||
|
this.modificationListener = modificationListener;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deactivate a wizard
|
* Deactivate a wizard
|
||||||
*/
|
*/
|
||||||
@ -2366,4 +2388,15 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
|||||||
void closed();
|
void closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener to get notified if the circuit has changed
|
||||||
|
*/
|
||||||
|
public interface ModificationListener {
|
||||||
|
/**
|
||||||
|
* Called if the circuit was modified
|
||||||
|
*
|
||||||
|
* @param modification the modification
|
||||||
|
*/
|
||||||
|
void modified(Modification<Circuit> modification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.gui.tutorial;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.NodeException;
|
||||||
|
import de.neemann.digital.core.basic.XOr;
|
||||||
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
|
import de.neemann.digital.core.element.Keys;
|
||||||
|
import de.neemann.digital.core.io.In;
|
||||||
|
import de.neemann.digital.core.io.Out;
|
||||||
|
import de.neemann.digital.draw.elements.Circuit;
|
||||||
|
import de.neemann.digital.draw.elements.PinException;
|
||||||
|
import de.neemann.digital.draw.elements.VisualElement;
|
||||||
|
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||||
|
import de.neemann.digital.draw.model.ModelCreator;
|
||||||
|
import de.neemann.digital.gui.Main;
|
||||||
|
import de.neemann.digital.gui.Settings;
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
|
import de.neemann.digital.gui.components.modification.ModifyInsertWire;
|
||||||
|
import de.neemann.digital.lang.Lang;
|
||||||
|
import de.neemann.digital.undo.Modification;
|
||||||
|
import de.neemann.digital.undo.Modifications;
|
||||||
|
import de.neemann.gui.LineBreaker;
|
||||||
|
import de.neemann.gui.Screen;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tutorial dialog.
|
||||||
|
*/
|
||||||
|
public class InitialTutorial extends JDialog implements CircuitComponent.ModificationListener {
|
||||||
|
private static final ArrayList<Step> STEPS = new ArrayList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
STEPS.add(new Step("tutorial1", (cc, mod, t) -> contains(cc, In.DESCRIPTION)));
|
||||||
|
STEPS.add(new Step("tutorial2", (cc, mod, t) -> contains(cc, In.DESCRIPTION, In.DESCRIPTION)));
|
||||||
|
STEPS.add(new Step("tutorial3", (cc, mod, t) -> contains(cc, In.DESCRIPTION, In.DESCRIPTION, XOr.DESCRIPTION)));
|
||||||
|
STEPS.add(new Step("tutorial4", (cc, mod, t) -> contains(cc, In.DESCRIPTION, In.DESCRIPTION, XOr.DESCRIPTION, Out.DESCRIPTION)));
|
||||||
|
STEPS.add(new Step("tutorial5", (cc, mod, t) -> contains(mod, ModifyInsertWire.class)));
|
||||||
|
STEPS.add(new Step("tutorial6", (cc, mod, t) -> isWorking(cc)));
|
||||||
|
STEPS.add(new Step("tutorial7", (cc, mod, t) -> cc.isRunning()));
|
||||||
|
STEPS.add(new Step("tutorial8", (cc, mod, t) -> !cc.isRunning()));
|
||||||
|
STEPS.add(new Step("tutorial9", (cc, mod, t) -> isIONamed(cc, 1, t)));
|
||||||
|
STEPS.add(new Step("tutorial10", (cc, mod, t) -> isIONamed(cc, 3, t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isIONamed(CircuitComponent cc, int expected, InitialTutorial t) {
|
||||||
|
HashSet<String> set = new HashSet<>();
|
||||||
|
int num = 0;
|
||||||
|
for (VisualElement ve : cc.getCircuit().getElements()) {
|
||||||
|
if (ve.equalsDescription(In.DESCRIPTION) || ve.equalsDescription(Out.DESCRIPTION)) {
|
||||||
|
String l = ve.getElementAttributes().getLabel();
|
||||||
|
if (!l.isEmpty()) {
|
||||||
|
if (set.contains(l)) {
|
||||||
|
t.setTextByID("tutorialUniqueIdents");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
set.add(l);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num == expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isWorking(CircuitComponent cc) {
|
||||||
|
try {
|
||||||
|
new ModelCreator(cc.getCircuit(), cc.getLibrary()).createModel(false);
|
||||||
|
return true;
|
||||||
|
} catch (PinException | NodeException | ElementNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean contains(Modification<Circuit> mod, Class<? extends Modification> modifyClass) {
|
||||||
|
if (mod == null)
|
||||||
|
return false;
|
||||||
|
if (mod.getClass() == modifyClass)
|
||||||
|
return true;
|
||||||
|
if (mod instanceof Modifications) {
|
||||||
|
Modifications m = (Modifications) mod;
|
||||||
|
for (Object i : m.getModifications())
|
||||||
|
if (i.getClass() == modifyClass)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean contains(CircuitComponent cc, ElementTypeDescription... descriptions) {
|
||||||
|
ArrayList<VisualElement> el = new ArrayList<>(cc.getCircuit().getElements());
|
||||||
|
if (el.size() != descriptions.length)
|
||||||
|
return false;
|
||||||
|
for (ElementTypeDescription d : descriptions) {
|
||||||
|
Iterator<VisualElement> it = el.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
if (it.next().equalsDescription(d)) {
|
||||||
|
it.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return el.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final JTextPane text;
|
||||||
|
private final CircuitComponent circuitComponent;
|
||||||
|
private int stepIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the tutorial dialog.
|
||||||
|
* @param main the main class
|
||||||
|
*/
|
||||||
|
public InitialTutorial(Main main) {
|
||||||
|
super(main, Lang.get("tutorial"), false);
|
||||||
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
|
setAlwaysOnTop(true);
|
||||||
|
circuitComponent = main.getCircuitComponent();
|
||||||
|
circuitComponent.setModificationListener(this);
|
||||||
|
|
||||||
|
addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent windowEvent) {
|
||||||
|
circuitComponent.setModificationListener(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
text = new JTextPane();
|
||||||
|
text.setEditable(false);
|
||||||
|
text.setFont(Screen.getInstance().getFont(1.2f));
|
||||||
|
text.setPreferredSize(new Dimension(300, 400));
|
||||||
|
|
||||||
|
getContentPane().add(new JScrollPane(text));
|
||||||
|
|
||||||
|
pack();
|
||||||
|
|
||||||
|
final Point ml = main.getLocation();
|
||||||
|
setLocation(ml.x - getWidth(), ml.y);
|
||||||
|
|
||||||
|
stepIndex = -1;
|
||||||
|
incIndex();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void incIndex() {
|
||||||
|
stepIndex++;
|
||||||
|
if (stepIndex == STEPS.size()) {
|
||||||
|
Settings.getInstance().getAttributes().set(Keys.SETTINGS_SHOW_TUTORIAL, false);
|
||||||
|
dispose();
|
||||||
|
} else {
|
||||||
|
setTextByID(STEPS.get(stepIndex).getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTextByID(String id) {
|
||||||
|
final String s = Lang.get(id);
|
||||||
|
text.setText(new LineBreaker(1000).breakLines(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void modified(Modification<Circuit> modification) {
|
||||||
|
if (STEPS.get(stepIndex).getChecker().accomplished(circuitComponent, modification, this))
|
||||||
|
incIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Step {
|
||||||
|
private final String id;
|
||||||
|
private final Checker checker;
|
||||||
|
|
||||||
|
private Step(String id, Checker checker) {
|
||||||
|
this.id = id;
|
||||||
|
this.checker = checker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Checker getChecker() {
|
||||||
|
return checker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface Checker {
|
||||||
|
boolean accomplished(CircuitComponent circuitComponent, Modification<Circuit> modification, InitialTutorial t);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classes used to show the initial tutorial
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.gui.tutorial;
|
@ -27,6 +27,13 @@ public final class Modifications<A extends Copyable<A>> implements Modification<
|
|||||||
m.modify(a);
|
m.modify(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The contained modifications
|
||||||
|
*/
|
||||||
|
public ArrayList<Modification<A>> getModifications() {
|
||||||
|
return modifications;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name;
|
||||||
|
@ -82,21 +82,27 @@ public class LineBreaker {
|
|||||||
|
|
||||||
StringBuilder word = new StringBuilder();
|
StringBuilder word = new StringBuilder();
|
||||||
pos = indent;
|
pos = indent;
|
||||||
|
boolean lastLineBreak=false;
|
||||||
for (int i = 0; i < text.length(); i++) {
|
for (int i = 0; i < text.length(); i++) {
|
||||||
char c = text.charAt(i);
|
char c = text.charAt(i);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n':
|
case '\n':
|
||||||
if (preserveLineBreaks) {
|
if (preserveLineBreaks || lastLineBreak) {
|
||||||
addWord(word);
|
addWord(word);
|
||||||
lineBreak();
|
lineBreak();
|
||||||
break;
|
} else {
|
||||||
|
addWord(word);
|
||||||
|
lastLineBreak = true;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
case ' ':
|
case ' ':
|
||||||
addWord(word);
|
addWord(word);
|
||||||
|
lastLineBreak = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
word.append(c);
|
word.append(c);
|
||||||
|
lastLineBreak = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addWord(word);
|
addWord(word);
|
||||||
|
@ -1348,6 +1348,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
|||||||
<string name="key_isGeneric">Schaltung ist generisch</string>
|
<string name="key_isGeneric">Schaltung ist generisch</string>
|
||||||
<string name="key_isGeneric_tt">Erlaubt die Erzeugung von generischen Schaltungen.</string>
|
<string name="key_isGeneric_tt">Erlaubt die Erzeugung von generischen Schaltungen.</string>
|
||||||
|
|
||||||
|
<string name="key_showTutorial">Tutorial beim Start anzeigen</string>
|
||||||
|
<string name="key_showTutorial_tt">Aktiviert das Tutorial.</string>
|
||||||
|
|
||||||
<string name="mod_insertWire">Leitung eingefügt.</string>
|
<string name="mod_insertWire">Leitung eingefügt.</string>
|
||||||
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>
|
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>
|
||||||
<string name="mod_setKey_N0_in_element_N1">Wert ''{0}'' in Element ''{1}'' verändert.</string>
|
<string name="mod_setKey_N0_in_element_N1">Wert ''{0}'' in Element ''{1}'' verändert.</string>
|
||||||
@ -1949,4 +1952,57 @@ Daher steht auch das Signal 'D_out' zur Verfügung, um in diesem Fall den Wert z
|
|||||||
Gibt es aus einem Zustand keinen unbedingten Übergang, bleibt der Automat in diesem Zustand, wenn keine
|
Gibt es aus einem Zustand keinen unbedingten Übergang, bleibt der Automat in diesem Zustand, wenn keine
|
||||||
andere Übergangsbedingung erfüllt ist.
|
andere Übergangsbedingung erfüllt ist.
|
||||||
</body></html>]]></string>
|
</body></html>]]></string>
|
||||||
|
|
||||||
|
<string name="tutorial">Tutorial</string>
|
||||||
|
<string name="tutorial1">Im Folgenden werden Sie mit einem kurzen Tutorial zur ersten
|
||||||
|
Schaltung geführt:
|
||||||
|
|
||||||
|
Fügen Sie einen Eingang in die Schaltung ein.
|
||||||
|
Sie finden den Eingang im Menu Bauteile▸IO.</string>
|
||||||
|
<string name="tutorial2">Fügen Sie nun einen zweiten Eingang in die Schaltung ein.
|
||||||
|
Sie können auch auf den Eingang in der Toolbar klicken.
|
||||||
|
|
||||||
|
Setzen Sie den zweiten Eingang am besten mit zwei Gitterabständen unter den ersten Eingang.
|
||||||
|
Sie können die Schaltung verschieben, wenn Sie die rechte Maustaste gedrückt halten.
|
||||||
|
Durch klicken auf die Eingänge können Sie diese verschieben.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial3">Als nächstes soll ein "Exklusiv Oder" Gatter eingefügt werden.
|
||||||
|
Sie finden dieses Gatter im Menu Bauteile▸Logisch.
|
||||||
|
Setzen Sie dieses Bauteil mit zwei Gitterabständen rechts neben die Eingänge.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial4">Als letztes Bauteil soll noch ein Ausgang eingefügt werden.
|
||||||
|
Setzen Sie diesen mit ebenfalls zwei Gitterabständen rechts neben das "Exklusiv Oder" Gatter.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial5">Um die Schaltung zu vervollständigen, sind Verbindungsleitungen zu ziehen.
|
||||||
|
|
||||||
|
Klicken Sie auf den roten Punkt am ersten Eingang und verbinden Sie diesen mit einem Eingang
|
||||||
|
des "Exklusiv Oder" Gatters, indem Sie danach auf einen blauen Punkt des "Exklusiv Oder"
|
||||||
|
Gatters klicken.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial6">Verbinden Sie die roten Punkte der Eingänge mit den blauen Punkten des
|
||||||
|
"Exklusiv Oder" Gatters und den roten Punkt des "Exklusiv Oder" Gatters mit dem blauen Punkte
|
||||||
|
des Ausgangs.
|
||||||
|
|
||||||
|
Durch Klicken können Sie die Leitung anheften. Rechts-Klick bricht das Zeichnen der Leitung ab.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial7">Damit ist Ihre erste Schaltung funktionsfähig.
|
||||||
|
Um die Simulation zu starten, können Sie auf den Play-Knopf in der Toolbar klicken.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial8">
|
||||||
|
Die Simulation ist jetzt aktiv.
|
||||||
|
Jetzt können Sie die Eingänge umschalten indem Sie darauf klicken.
|
||||||
|
Um die Simulation zu beenden, klicken Sie auf den Stop-Knopf in der Toolbar.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial9">
|
||||||
|
Der Vollständigkeit halber sollen die Ein- und Ausgänge benannt werden.
|
||||||
|
|
||||||
|
Durch Rechts-Klick auf einen Ausgang öffnet sich ein Dialog.
|
||||||
|
Hier kann der Ausgang mit einer Bezeichnung versehen werden.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial10">
|
||||||
|
Benennen Sie alle Ein- und Ausgänge.
|
||||||
|
</string>
|
||||||
|
<string name="tutorialUniqueIdents">
|
||||||
|
Die Ein- und Ausgänge sollten eindeutig benannt sein.
|
||||||
|
</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1334,6 +1334,9 @@
|
|||||||
<string name="key_isGeneric">Circuit is generic</string>
|
<string name="key_isGeneric">Circuit is generic</string>
|
||||||
<string name="key_isGeneric_tt">Allows to create a generic circuit.</string>
|
<string name="key_isGeneric_tt">Allows to create a generic circuit.</string>
|
||||||
|
|
||||||
|
<string name="key_showTutorial">Show Tutorial at Startup</string>
|
||||||
|
<string name="key_showTutorial_tt">Enables the tutorial.</string>
|
||||||
|
|
||||||
<string name="mod_insertWire">Inserted wire.</string>
|
<string name="mod_insertWire">Inserted wire.</string>
|
||||||
<string name="mod_insertCopied">Insert from clipboard.</string>
|
<string name="mod_insertCopied">Insert from clipboard.</string>
|
||||||
<string name="mod_setKey_N0_in_element_N1">Value ''{0}'' in component ''{1}'' modified.</string>
|
<string name="mod_setKey_N0_in_element_N1">Value ''{0}'' in component ''{1}'' modified.</string>
|
||||||
@ -1918,4 +1921,48 @@ Therefore, the signal 'D_out' is also available to check the value in this case.
|
|||||||
transition condition is met.
|
transition condition is met.
|
||||||
</body></html>]]></string>
|
</body></html>]]></string>
|
||||||
|
|
||||||
|
<string name="tutorial">Tutorial</string>
|
||||||
|
<string name="tutorial1">In the following you will be guided to the first circuit with a short tutorial:
|
||||||
|
|
||||||
|
Add an input into the circuit. You will find the input in the menu Components▸IO.</string>
|
||||||
|
<string name="tutorial2">Now add a second input to the circuit. You can also click on the input
|
||||||
|
in the toolbar.
|
||||||
|
|
||||||
|
It is best to place the second input with two grid spacings under the first input.
|
||||||
|
You can move the circuit by holding down the right mouse button.
|
||||||
|
By clicking on the inputs you can move them.</string>
|
||||||
|
<string name="tutorial3">Next, an "Exclusive Or" gate is to be inserted.
|
||||||
|
You can find this gate in the menu Components▸Logic.
|
||||||
|
Place this component with two grid spacings to the right of the inputs.</string>
|
||||||
|
<string name="tutorial4">The last component to be inserted is an output.
|
||||||
|
Set it with two grid spacings to the right of the "Exclusive Or" gate.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial5">In order to complete the circuit, connecting wires must be drawn.
|
||||||
|
|
||||||
|
Click on the red dot at the first input and connect it to an input of the "Exclusive Or" gate,
|
||||||
|
by clicking on a blue dot of the "Exclusive Or" gate.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial6">Connect the red dots of the inputs to the blue dots of the
|
||||||
|
"Exclusive Or" gate and the red dot of the "Exclusive Or" gate to the blue dot of the output.
|
||||||
|
|
||||||
|
You can pin the wire by clicking. Right-click cancels the drawing of the wire.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial7">Your first circuit is now functional.
|
||||||
|
To start the simulation, you can click on the Play button in the toolbar.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial8">
|
||||||
|
The simulation is now active. Now you can switch the inputs by clicking on them.
|
||||||
|
To stop the simulation, click on the Stop button in the toolbar.
|
||||||
|
</string>
|
||||||
|
<string name="tutorial9">
|
||||||
|
For completeness, the inputs and outputs should be labeled.
|
||||||
|
|
||||||
|
Right-click on an output to open a dialog. Here the output can be given a name.</string>
|
||||||
|
<string name="tutorial10">
|
||||||
|
Label all inputs and outputs.
|
||||||
|
</string>
|
||||||
|
<string name="tutorialUniqueIdents">
|
||||||
|
The inputs and outputs should be uniquely named.
|
||||||
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -68,7 +68,7 @@ public class TestLang extends TestCase {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (String key : map.keySet()) {
|
for (String key : map.keySet()) {
|
||||||
if (!keys.contains(key)) {
|
if (!keys.contains(key)) {
|
||||||
if (!(key.startsWith("key_") || key.startsWith("elem_"))) {
|
if (!(key.startsWith("key_") || key.startsWith("elem_") || key.startsWith("tutorial"))) {
|
||||||
if (sb.length() > 0)
|
if (sb.length() > 0)
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
sb.append('"').append(key).append('"');
|
sb.append('"').append(key).append('"');
|
||||||
|
@ -12,8 +12,8 @@ import junit.framework.TestCase;
|
|||||||
public class LineBreakerTest extends TestCase {
|
public class LineBreakerTest extends TestCase {
|
||||||
|
|
||||||
public void testBreakLines() throws Exception {
|
public void testBreakLines() throws Exception {
|
||||||
assertEquals("this is a test string", new LineBreaker(60).breakLines("this \n\n is \n a test \n\r string"));
|
assertEquals("this\nis a test string", new LineBreaker(60).breakLines("this \n\n is \n a test \n\r string"));
|
||||||
assertEquals("this is a test\nstring", new LineBreaker(14).breakLines("this \n\n is \n a test \n\r string"));
|
assertEquals("this\nis a test\nstring", new LineBreaker(14).breakLines("this \n\n is \n a test \n\r string"));
|
||||||
assertEquals("This is a test string. This\n" +
|
assertEquals("This is a test string. This\n" +
|
||||||
"is a test string. This is a\n" +
|
"is a test string. This is a\n" +
|
||||||
"test string.", new LineBreaker(27).breakLines("This is a test string. This is a test string. This is a test string."));
|
"test string.", new LineBreaker(27).breakLines("This is a test string. This is a test string. This is a test string."));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user