summaryrefslogtreecommitdiff
path: root/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/bindings/AbstractTableWidget.java
blob: 99f232a3b9491814454b97c48acaad03b8501866 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package edu.wpi.first.smartdashboard.gui.elements.bindings;

import edu.wpi.first.smartdashboard.gui.*;
import edu.wpi.first.smartdashboard.livewindow.elements.LWSubsystem;
import edu.wpi.first.smartdashboard.livewindow.elements.NameTag;
import edu.wpi.first.smartdashboard.types.DataType;
import edu.wpi.first.wpilibj.tables.*;
import java.awt.Point;
import java.util.*;
import javax.swing.JComboBox;

/**
 * An abstraction for creating a widget that wraps a network table
 * 
 * 
 * @author Mitchell
 *
 */
public abstract class AbstractTableWidget extends Widget implements ITableListener{
    protected ITable table;

    /** A NameTag for this widget. */
    public NameTag nameTag;
    
	private final boolean listenSubtables;
    
	public AbstractTableWidget(){
		this(false);
	}
	protected AbstractTableWidget(boolean listenSubtables){
		this.listenSubtables = listenSubtables;
	}

	@Override
	public void setValue(Object value) {
		if(value instanceof ITable){
			ITable table = (ITable)value;

			if (table != null)
				table.removeTableListener(this);

			this.table = table;
			if(table!=null){
				table.addTableListener(this, true);
				if(listenSubtables)
					table.addSubTableListener(this);
			}
		}
	}
    
    public void setField(String name, Widget element, DataType type, Object value, LWSubsystem subsystem, Point point) {
        element.setFieldName(name);
        element.setType(type);
        element.init();
        if(value != null) {
            element.setValue(value);
        }
        subsystem.addWidget(element);
    }

	private Map<String, List<BooleanBindable>> booleanFields = new HashMap<>();
	private Map<String, List<NumberBindable>> numberFields = new HashMap<>();
	private Map<String, List<StringBindable>> stringFields = new HashMap<>();
	@Override
	public void valueChanged(ITable source, String key, Object value, boolean isNew) {
		if(value instanceof Boolean)
			booleanChanged(source, key, ((Boolean)value).booleanValue(), isNew);
		if(value instanceof Double)
			doubleChanged(source, key, ((Double)value).doubleValue(), isNew);
		if(value instanceof String)
			stringChanged(source, key, (String)value, isNew);
		if(value instanceof ITable)
			tableChanged(source, key, (ITable)value, isNew);
	}


	public void booleanChanged(ITable source, String key, boolean value, boolean isNew) {
                if(!booleanFields.containsKey(key)) booleanFields.put(key, new ArrayList<>());
		List<BooleanBindable> field = booleanFields.get(key);
                field.stream().forEach(bindable -> bindable.setBindableValue(value));
	}
	public void doubleChanged(ITable source, String key, double value, boolean isNew) {
                if(!numberFields.containsKey(key)) numberFields.put(key, new ArrayList<>());
		List<NumberBindable> field = numberFields.get(key);
                field.stream().forEach(bindable -> bindable.setBindableValue(value));
	}
	public void stringChanged(ITable source, String key, String value, boolean isNew) {
                if(!stringFields.containsKey(key)) stringFields.put(key, new ArrayList<>());
		List<StringBindable> field = stringFields.get(key);
                field.stream().forEach(bindable -> bindable.setBindableValue(value));
	}
	public void tableChanged(ITable source, String key, ITable value, boolean isNew) {
	}


	public MultiTypeBindable getTableEntryBindable(final String key){
		return new MultiTypeBindable(){
			@Override
			public void setBindableValue(boolean value) {
				if(table!=null)
					table.putBoolean(key, value);
			}
			@Override
			public void setBindableValue(double value) {
				if(table!=null)
					table.putNumber(key, value);
			}
			@Override
			public void setBindableValue(String value) {
				if(table!=null)
					table.putString(key, value);
			}
		};
	}


	protected void setBooleanBinding(String key, BooleanBindable displayer){
                if(!booleanFields.containsKey(key)) booleanFields.put(key, new ArrayList<>());
		booleanFields.get(key).add(displayer);
	}
	protected void setNumberBinding(String key, NumberBindable displayer){
                if(!numberFields.containsKey(key)) numberFields.put(key, new ArrayList<>());
		numberFields.get(key).add(displayer);
	}
	protected void setStringBinding(String key, StringBindable displayer, String defaultValue){
                displayer.setBindableValue(defaultValue);
                if(!stringFields.containsKey(key)) stringFields.put(key, new ArrayList<>());
		stringFields.get(key).add(displayer);
	}



	
	public class BooleanTableCheckBox extends BindableBooleanCheckBox{
		public BooleanTableCheckBox(final String key){
			super(getTableEntryBindable(key));
			setBooleanBinding(key, this);
		}
	}
	public class BooleanTableField extends BindableBooleanField{
		public BooleanTableField(final String key){
			super(getTableEntryBindable(key));
			setBooleanBinding(key, this);
		}
	}
	public class NumberTableField extends BindableNumberField{
		public NumberTableField(final String key){
			super(getTableEntryBindable(key));
			setNumberBinding(key, this);
		}
	}
	public class StringTableField extends BindableStringField{
		public StringTableField(final String key){
			super(getTableEntryBindable(key));
			setStringBinding(key, this, "");
		}
	}
        public class StringTableComboBox extends JComboBox<String> implements StringBindable {
                public StringTableComboBox(final String key, String... items) {
                    super(items);
                    getTableEntryBindable(key);
                    setStringBinding(key, this, "");
                    addActionListener(e -> table.putString(key, (String) getSelectedItem()));
                }
                @Override
                public void setBindableValue(String value) {
                    setSelectedItem(value);
                }
        }
        public class NumberTableComboBox<E> extends JComboBox<E> implements NumberBindable {
                public NumberTableComboBox(final String key, E... items) {
                    super(items);
                    getTableEntryBindable(key);
                    setNumberBinding(key, this);
                    addActionListener(e -> table.putNumber(key, getSelectedIndex()));
                }
                @Override
                public void setBindableValue(double value) {
                    if((int) value == value && value >= 0 && value < getItemCount())
                    setSelectedIndex((int) value);
                }
        }
}