Added a tabbed pane to the attributes dialog to make it more beginner friendly.

This commit is contained in:
hneemann 2018-05-19 12:49:56 +02:00
parent 28db768c8e
commit ebc596e3f6
43 changed files with 129 additions and 39 deletions

View File

@ -1,6 +1,7 @@
Release Notes
HEAD, planned as v0.19
- Added a tabbed pane to the attributes dialog to make it more beginner friendly.
- Added support for asynchronous sequential circuits such as the Muller-pipeline.
Take a look at the new asynchronous examples for illustration.
- All examples are translated to english.

View File

@ -26,6 +26,7 @@ public class Key<VALUE> {
// Both are only used within a custom implemented component.
private String name;
private String description;
private boolean isSecondary;
/**
* Creates a new Key
@ -183,6 +184,23 @@ public class Key<VALUE> {
return this;
}
/**
* @return true is this is a secondary attribute
*/
public boolean isSecondary() {
return isSecondary;
}
/**
* Makes this attribute to be a secondary attribute
*
* @return this for chained calls
*/
public Key<VALUE> setSecondary() {
isSecondary = true;
return this;
}
/**
* A integer attribute.
* Stores additional combo box values

View File

@ -140,7 +140,8 @@ public final class Keys {
= new Key.KeyInteger("Size", 1)
.setComboBoxValues(new Integer[]{0, 1, 2, 3, 4, 5})
.setMin(0)
.allowGroupEdit();
.allowGroupEdit()
.setSecondary();
/**
* The value of constants
@ -152,19 +153,19 @@ public final class Keys {
* The default value of elements
*/
public static final Key<Integer> DEFAULT
= new Key<>("Default", 0).allowGroupEdit();
= new Key<>("Default", 0).allowGroupEdit().setSecondary();
/**
* The default value of inputs
*/
public static final Key<InValue> INPUT_DEFAULT
= new Key<>("InDefault", new InValue(0)).allowGroupEdit();
= new Key<>("InDefault", new InValue(0)).allowGroupEdit().setSecondary();
/**
* The default value of the dip switch
*/
public static final Key<Boolean> DIP_DEFAULT
= new Key<>("dipDefault", false);
= new Key<>("dipDefault", false).allowGroupEdit().setSecondary();
/**
@ -188,11 +189,12 @@ public final class Keys {
/**
* The splitter spreading
*/
public static final Key.KeyInteger SPLITTER_SPREADING
public static final Key<Integer> SPLITTER_SPREADING
= new Key.KeyInteger("splitterSpreading", 1)
.setComboBoxValues(new Integer[]{1, 2, 3, 4})
.setMin(1)
.setMax(10);
.setMax(10)
.setSecondary();
/**
@ -262,7 +264,7 @@ public final class Keys {
* the rotation of the elements
*/
public static final Key<Rotation> ROTATE
= new Key<>("rotation", new Rotation(0)).allowGroupEdit();
= new Key<>("rotation", new Rotation(0)).allowGroupEdit().setSecondary();
/**
* the width of an element if it is included as nested element
@ -296,37 +298,37 @@ public final class Keys {
* flag to make a value a probe
*/
public static final Key<Boolean> VALUE_IS_PROBE
= new Key<>("valueIsProbe", false).allowGroupEdit();
= new Key<>("valueIsProbe", false).allowGroupEdit().setSecondary();
/**
* flag to set a ROM as program memory
*/
public static final Key<Boolean> IS_PROGRAM_MEMORY
= new Key<>("isProgramMemory", false);
= new Key<>("isProgramMemory", false).setSecondary();
/**
* flag to enable the ROMs auto load function
*/
public static final Key<Boolean> AUTO_RELOAD_ROM
= new Key<>("autoReload", false);
= new Key<>("autoReload", false).setSecondary();
/**
* flag to show the data table window
*/
public static final Key<Boolean> SHOW_DATA_TABLE
= new Key<>("showDataTable", false);
= new Key<>("showDataTable", false).setSecondary();
/**
* flag to show the data graph window
*/
public static final Key<Boolean> SHOW_DATA_GRAPH
= new Key<>("showDataGraph", false);
= new Key<>("showDataGraph", false).setSecondary();
/**
* flag to show the data graph window in single gate mode
*/
public static final Key<Boolean> SHOW_DATA_GRAPH_MICRO
= new Key<>("showDataGraphMicro", false);
= new Key<>("showDataGraphMicro", false).setSecondary();
/**
* flag to enable the single gate mode in the embedded data view
@ -345,7 +347,7 @@ public final class Keys {
* flag to enable high z mode at an input
*/
public static final Key<Boolean> IS_HIGH_Z
= new Key<>("isHighZ", false).allowGroupEdit();
= new Key<>("isHighZ", false).allowGroupEdit().setSecondary();
/**
* the description of an element
@ -405,8 +407,8 @@ public final class Keys {
/**
* output format for numbers
*/
public static final Key.KeyEnum<IntFormat> INT_FORMAT
= new Key.KeyEnum<>("intFormat", IntFormat.def, IntFormat.values());
public static final Key<IntFormat> INT_FORMAT
= new Key.KeyEnum<>("intFormat", IntFormat.def, IntFormat.values()).setSecondary();
/**
* width of the terminal
@ -462,13 +464,13 @@ public final class Keys {
* Fitter for the atf15xx
*/
public static final Key<File> SETTINGS_ATF1502_FITTER
= new Key.KeyFile("atf1502Fitter", new File("c:/Wincupl/WinCupl/Fitters")).setDirectoryOnly(true);
= new Key.KeyFile("atf1502Fitter", new File("c:/Wincupl/WinCupl/Fitters")).setDirectoryOnly(true).setSecondary();
/**
* Flash software for the atf15xx
*/
public static final Key<File> SETTINGS_ATMISP
= new Key.KeyFile("ATMISP", new File("c:/ATMISP7/ATMISP.exe"));
= new Key.KeyFile("ATMISP", new File("c:/ATMISP7/ATMISP.exe")).setSecondary();
/**
* row bits in led matrix
@ -492,20 +494,21 @@ public final class Keys {
* the pin number
*/
public static final Key<String> PINNUMBER =
new Key<>("pinNumber", "");
new Key<>("pinNumber", "").setSecondary();
/**
* true if shape is a dil shape
*/
public static final Key<Boolean> IS_DIL
= new Key<>("isDIL", false);
= new Key<>("isDIL", false).setSecondary();
/**
* the pin count
*/
public static final Key<Integer> PINCOUNT =
new Key.KeyInteger("pinCount", 0)
.setMin(0)
.setDependsOn(IS_DIL);
.setDependsOn(IS_DIL)
.setSecondary();
/**
@ -558,19 +561,19 @@ public final class Keys {
* Fitter for the atf1502
*/
public static final Key<File> SETTINGS_LIBRARY_PATH
= new Key.KeyFile("libraryPath", ElementLibrary.getLibPath()).setDirectoryOnly(true);
= new Key.KeyFile("libraryPath", ElementLibrary.getLibPath()).setDirectoryOnly(true).setSecondary();
/**
* A jar containing custom java components
*/
public static final Key<File> SETTINGS_JAR_PATH
= new Key.KeyFile("jarPath", new File(""));
= new Key.KeyFile("jarPath", new File("")).setSecondary();
/**
* The manager which contains all the roms data
*/
public static final Key<ROMManger> ROMMANAGER
= new Key<>("romContent", ROMManger.EMPTY);
= new Key<>("romContent", ROMManger.EMPTY).setSecondary();
/**
@ -597,8 +600,8 @@ public final class Keys {
/**
* Path to ghdl
*/
public static final Key.KeyFile SETTINGS_GHDL_PATH
= new Key.KeyFile("ghdlPath", new File("ghdl"));
public static final Key<File> SETTINGS_GHDL_PATH
= new Key.KeyFile("ghdlPath", new File("ghdl")).setSecondary();
/**
* Avoid component tooltips in the main panel
@ -616,6 +619,6 @@ public final class Keys {
* Shape used to represent a visual element
*/
public static final Key<CustomShapeDescription> CUSTOM_SHAPE
= new Key<>("customShape", CustomShapeDescription.EMPTY);
= new Key<>("customShape", CustomShapeDescription.EMPTY).setSecondary();
}

View File

@ -40,8 +40,8 @@ public class Multiplexer extends FanIn {
}
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
.addAttribute(Keys.FLIP_SEL_POSITON)
.addAttribute(Keys.SELECTOR_BITS);
.addAttribute(Keys.SELECTOR_BITS)
.addAttribute(Keys.FLIP_SEL_POSITON);
/**
* Creates a new instance

View File

@ -20,6 +20,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Dialog used to edit Attributes.
@ -85,16 +86,31 @@ public class AttributeDialog extends JDialog {
panel = new JPanel(new GridBagLayout());
getContentPane().add(new JScrollPane(panel));
editors = new ArrayList<>();
topMostTextComponent = null;
constraints = new ConstraintsBuilder().inset(3).fill();
JPanel secondaryPanel = null;
ConstraintsBuilder secondaryConstraints = null;
boolean enableTwoTabs = !addCheckBoxes && enableTwoTabs(list);
if (enableTwoTabs) {
secondaryPanel = new JPanel(new GridBagLayout());
secondaryConstraints = new ConstraintsBuilder().inset(3).fill();
}
boolean isSecondary = false;
for (Key key : list) {
Editor e = EditorFactory.INSTANCE.create(key, modifiedAttributes.get(key));
editors.add(new EditorHolder(e, key));
e.addToPanel(panel, key, modifiedAttributes, this, constraints);
if (key.isSecondary() && enableTwoTabs) {
e.addToPanel(secondaryPanel, key, modifiedAttributes, this, secondaryConstraints);
isSecondary = true;
} else
e.addToPanel(panel, key, modifiedAttributes, this, constraints);
if (addCheckBoxes) {
if (checkBoxes == null)
checkBoxes = new HashMap<>();
@ -105,7 +121,11 @@ public class AttributeDialog extends JDialog {
panel.add(checkBox, constraints.x(2));
checkBox.addChangeListener(event -> e.setEnabled(checkBox.isSelected()));
}
constraints.nextRow();
if (key.isSecondary() && enableTwoTabs)
secondaryConstraints.nextRow();
else
constraints.nextRow();
if (topMostTextComponent == null && e instanceof EditorFactory.StringEditor)
topMostTextComponent = ((EditorFactory.StringEditor) e).getTextComponent();
@ -121,6 +141,15 @@ public class AttributeDialog extends JDialog {
}
if (isSecondary) {
JTabbedPane tp = new JTabbedPane(JTabbedPane.TOP);
tp.addTab(Lang.get("attr_primary"), new JScrollPane(panel));
tp.addTab(Lang.get("attr_secondary"), new JScrollPane(secondaryPanel));
getContentPane().add(tp);
} else
getContentPane().add(new JScrollPane(panel));
JButton okButton = new JButton(new AbstractAction(Lang.get("ok")) {
@Override
public void actionPerformed(ActionEvent e) {
@ -151,6 +180,25 @@ public class AttributeDialog extends JDialog {
JComponent.WHEN_IN_FOCUSED_WINDOW);
}
/**
* Returns true if two tabs are to be used.
*
* @param list the list a keys
* @return true if two tabs are to be used.
*/
public boolean enableTwoTabs(List<Key> list) {
int secCount = 0;
int primCount = 0;
for (Key k : list) {
if (k.isSecondary())
secCount++;
else
primCount++;
}
return (primCount > 1) && (secCount > 1);
}
/**
* Closes the dialog and stores modified values
*

View File

@ -34,7 +34,7 @@ public class CustomShapeEditor extends EditorFactory.LabelEditor<CustomShapeDesc
@Override
public JComponent getComponent(ElementAttributes attr) {
JPanel panel = new JPanel(new FlowLayout());
JPanel panel = new JPanel(new GridLayout(1, 2));
panel.add(new ToolTipAction(Lang.get("btn_clearData")) {
@Override
public void actionPerformed(ActionEvent e) {

View File

@ -465,7 +465,7 @@ public final class EditorFactory {
@Override
public JComponent getComponent(ElementAttributes attr) {
JPanel panel = new JPanel(new FlowLayout());
JPanel panel = new JPanel(new GridLayout(1, 2));
panel.add(new ToolTipAction(Lang.get("btn_edit")) {
@Override
public void actionPerformed(ActionEvent e) {

View File

@ -231,7 +231,11 @@ public class ElementHelpDialog extends JDialog {
if (et.getAttributeList().size() > 0) {
w.append("<h4>").append(Lang.get("elem_Help_attributes")).append(":</h4>\n<dl>\n");
for (Key k : et.getAttributeList())
writeEntry(w, k.getName(), k.getDescription());
if (!k.isSecondary())
writeEntry(w, k.getName(), k.getDescription());
for (Key k : et.getAttributeList())
if (k.isSecondary())
writeEntry(w, k.getName(), k.getDescription());
w.append("</dl>\n");
}
}

View File

@ -18,6 +18,8 @@
<string name="attr_dialogHighz">HighZ</string>
<string name="attr_dialogOctal">Oktal</string>
<string name="attr_dialogBinary">Binär</string>
<string name="attr_primary">Standard</string>
<string name="attr_secondary">Erweitert</string>
<string name="btn_discard">Verwerfen</string>
<string name="btn_edit">Bearbeiten</string>
<string name="btn_editFurther">Weiter bearbeiten</string>

View File

@ -18,6 +18,8 @@
<string name="attr_dialogHighz">HighZ</string>
<string name="attr_dialogOctal">Octal</string>
<string name="attr_dialogBinary">Binary</string>
<string name="attr_primary">Basic</string>
<string name="attr_secondary">Advanced</string>
<string name="btn_discard">Discard Changes</string>
<string name="btn_edit">Edit</string>
<string name="btn_editFurther">Continue editing</string>

View File

@ -116,9 +116,18 @@ public class DocuTest extends TestCase {
if (etd.getAttributeList().size() > 0) {
w.append(" <attributes name=\"").append(Lang.get("elem_Help_attributes")).append("\">\n");
for (Key k : etd.getAttributeList()) {
w.append(" <attr name=\"").append(escapeHTML(k.getName())).append("\">");
w.append(escapeHTML(k.getDescription()));
w.append("</attr>\n");
if (!k.isSecondary()) {
w.append(" <attr name=\"").append(escapeHTML(k.getName())).append("\">");
w.append(escapeHTML(k.getDescription()));
w.append("</attr>\n");
}
}
for (Key k : etd.getAttributeList()) {
if (k.isSecondary()) {
w.append(" <attr name=\"").append(escapeHTML(k.getName())).append("\">");
w.append(escapeHTML(k.getDescription()));
w.append("</attr>\n");
}
}
w.append(" </attributes>\n");
}

View File

@ -44,6 +44,7 @@ public class ScreenShots {
public static void main(String[] args) {
Settings.getInstance().getAttributes().set(Keys.SETTINGS_DEFAULT_TREESELECT, false);
Settings.getInstance().getAttributes().set(Keys.SETTINGS_GRID, true);
// mainScreenShot();
// firstSteps();
// hierarchicalDesign();

View File

@ -766,6 +766,8 @@ public class TestInGUI extends TestCase {
.press("RIGHT", 2)
.press("DOWN", 1)
.press("ENTER", 1)
.press("control TAB", 4)
.press("RIGHT", 1)
.add(new GuiTester.SetFocusTo<>(AttributeDialog.class,
b -> b instanceof JButton && Lang.get("btn_edit").equals(((JButton) b).getText())))
.press("SPACE")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB