Skip to content

Commit f5ffed3

Browse files
authored
Merge pull request #74 from team5499/dev/selector
Add dropdown selector
2 parents 547f4e9 + bff91f0 commit f5ffed3

13 files changed

Lines changed: 225 additions & 19 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dependencies {
2727
}
2828

2929
group = 'org.team5499'
30-
version = '0.10.0' /* Change this when deploying a new version */
30+
version = '0.11.0' /* Change this when deploying a new version */
3131

3232
task sourcesJar(type: Jar) {
3333
from sourceSets.main.allJava
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package org.team5499.dashboard
2+
3+
interface DashboardType
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.team5499.dashboard
2+
3+
import org.json.JSONObject
4+
import org.json.JSONArray
5+
6+
@Suppress("SpreadOperator")
7+
class StringChooser(val dashboardName: String, val default: String, vararg initialOptions: String) : DashboardType {
8+
public var options: MutableList<String>
9+
public var selected: String
10+
get() {
11+
return Dashboard.getVariable<JSONObject>(dashboardName).getString("selected")
12+
}
13+
set(value) {
14+
Dashboard.setVariable(dashboardName, getBroadcastObject(value))
15+
}
16+
17+
init {
18+
options = mutableListOf(*initialOptions)
19+
selected = default
20+
}
21+
22+
private fun getBroadcastObject(value: String): JSONObject {
23+
val newJSON = JSONObject()
24+
val optionsJSON = JSONArray()
25+
options.forEach({
26+
optionsJSON.put(it)
27+
})
28+
newJSON.put("options", optionsJSON)
29+
newJSON.put("selected", value)
30+
newJSON.put("vartype", "StringChooser")
31+
return newJSON
32+
}
33+
34+
fun addVarListener(callback: VariableCallback): Int {
35+
return Dashboard.addVarListener(dashboardName) {
36+
key: String, value: Any? ->
37+
callback(key, (value as? JSONObject)!!.get("selected") as? Any)
38+
}
39+
}
40+
41+
fun removeVarListener(id: Int): Boolean {
42+
return Dashboard.removeVarListener(dashboardName, id)
43+
}
44+
45+
fun runIfUpdate(callback: VariableCallback): Boolean {
46+
return Dashboard.runIfUpdate(dashboardName) {
47+
key: String, value: Any? ->
48+
callback(key, (value as? JSONObject)!!.get("selected") as? Any)
49+
}
50+
}
51+
52+
fun addInlineListener(callback: VariableCallback): Int {
53+
return Dashboard.addInlineListener(dashboardName) {
54+
key: String, value: Any? ->
55+
callback(key, (value as? JSONObject)!!.get("selected") as? Any)
56+
}
57+
}
58+
59+
fun removeInlineListener(id: Int): Boolean {
60+
return Dashboard.removeInlineListener(dashboardName, id)
61+
}
62+
}

src/main/resources/page.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,6 @@
4747
<script src="/javascript/widgets/double-editor.jsx" data-plugins="transform-es2015-modules-umd" type="text/babel"></script>
4848
<script src="/javascript/widgets/pidf-widget.jsx" data-plugins="transform-es2015-modules-umd" type="text/babel"></script>
4949
<script src="/javascript/widgets/pid-widget.jsx" data-plugins="transform-es2015-modules-umd" type="text/babel"></script>
50+
<script src="/javascript/widgets/string-chooser.jsx" data-plugins="transform-es2015-modules-umd" type="text/babel"></script>
5051
<script src="/javascript/widgets/camera-widget.jsx" data-plugins="transform-es2015-modules-umd" type="text/babel"></script>
5152
{% endblock %}

src/main/resources/static/javascript/socket-handler.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,19 @@ export default class SocketHandler {
6565
}
6666

6767
static addVariableListener(key, callback) {
68-
if(!Array.isArray(callbacks[key])) {
69-
callbacks[key] = [];
68+
if(callbacks[key] === undefined) {
69+
callbacks[key] = {};
7070
}
71-
callbacks[key].push(callback);
72-
return callbacks[key].length - 1;
71+
let uid = key + Date.now().toString();
72+
callbacks[key][uid] = callback;
73+
return uid;
7374
}
7475

7576
static removeVariableListener(key, id) {
76-
callbacks[key].splice(id, 1);
77+
return delete callbacks[key][id];
7778
}
7879

79-
static _getVariable(key) {
80+
static getVariable(key) {
8081
if((!(key in variables)) && (!(key in variableUpdates))) {
8182
console.warn("variable " + key + " not found!");
8283
return undefined;
@@ -87,56 +88,56 @@ export default class SocketHandler {
8788
}
8889
}
8990

90-
static _setVariable(key, value) {
91+
static setVariable(key, value) {
9192
variableUpdates[key] = value;
9293
}
9394

9495
static setInt(key, value) {
9596
let newValue = parseInt(value);
96-
SocketHandler._setVariable(key, newValue);
97+
SocketHandler.setVariable(key, newValue);
9798
}
9899

99100
static setDouble(key, value) {
100101
let newValue = parseFloat(value);
101-
SocketHandler._setVariable(key, newValue);
102+
SocketHandler.setVariable(key, newValue);
102103
}
103104

104105
static setString(key, value) {
105106
let newValue = String(value);
106-
SocketHandler._setVariable(key, newValue);
107+
SocketHandler.setVariable(key, newValue);
107108
}
108109

109110
static setBoolean(key, value) {
110111
let newValue = Boolean(value);
111-
SocketHandler._setVariable(key, newValue);
112+
SocketHandler.setVariable(key, newValue);
112113
}
113114

114115
static getInt(key) {
115-
let value = SocketHandler._getVariable(key);
116+
let value = SocketHandler.getVariable(key);
116117
if(value === undefined) {
117118
return undefined;
118119
}
119120
return parseInt(value);
120121
}
121122

122123
static getDouble(key) {
123-
let value = SocketHandler._getVariable(key);
124+
let value = SocketHandler.getVariable(key);
124125
if(value === undefined) {
125126
return undefined;
126127
}
127128
return parseFloat(value);
128129
}
129130

130131
static getString(key) {
131-
let value = SocketHandler._getVariable(key);
132+
let value = SocketHandler.getVariable(key);
132133
if(value === undefined) {
133134
return undefined;
134135
}
135136
return String(value);
136137
}
137138

138139
static getBoolean(key) {
139-
let value = SocketHandler._getVariable(key);
140+
let value = SocketHandler.getVariable(key);
140141
if(value === undefined) {
141142
return undefined;
142143
}

src/main/resources/static/javascript/widget-components.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@ export class WidgetContainer extends React.Component {
5353
{React.createElement(this.props.widgetClass.Body,
5454
{registerVarListener: (variable, callback) => SocketHandler.addVariableListener(variable, callback),
5555
removeVarListener: (variable, id) => SocketHandler.removeVariableListener(variable, id),
56+
setVariable: (key, value) => SocketHandler.setVariable(key, value),
5657
setInt: (key, value) => SocketHandler.setInt(key, value),
5758
setDouble: (key, value) => SocketHandler.setDouble(key, value),
5859
setString: (key, value) => SocketHandler.setString(key, value),
5960
setBoolean: (key, value) => SocketHandler.setBoolean(key, value),
61+
getVariable: (key) => SocketHandler.getVariable(key),
6062
getInt: (key) => SocketHandler.getInt(key),
6163
getDouble: (key) => SocketHandler.getDouble(key),
6264
getString: (key) => SocketHandler.getString(key),
@@ -70,10 +72,12 @@ export class WidgetContainer extends React.Component {
7072
{React.createElement(this.props.widgetClass.Settings,
7173
{registerVarListener: (variable, callback) => SocketHandler.addVariableListener(variable, callback),
7274
removeVarListener: (variable, id) => SocketHandler.removeVariableListener(variable, id),
75+
setVariable: (key, value) => SocketHandler.setVariable(key, value),
7376
setInt: (key, value) => SocketHandler.setInt(key, value),
7477
setDouble: (key, value) => SocketHandler.setDouble(key, value),
7578
setString: (key, value) => SocketHandler.setString(key, value),
7679
setBoolean: (key, value) => SocketHandler.setBoolean(key, value),
80+
getVariable: (key) => SocketHandler.getVariable(key),
7781
getInt: (key) => SocketHandler.getInt(key),
7882
getDouble: (key) => SocketHandler.getDouble(key),
7983
getString: (key) => SocketHandler.getString(key),

src/main/resources/static/javascript/widget.jsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ Widget.Body = class extends React.Component {
2323
return this.settingsSave(newConfig);
2424
}
2525

26+
getVariable(key) {
27+
return this.props.getVariable(key);
28+
}
29+
2630
getInt(key) {
2731
return this.props.getInt(key);
2832
}
@@ -39,6 +43,10 @@ Widget.Body = class extends React.Component {
3943
return this.props.getBoolean(key);
4044
}
4145

46+
setVariable(key, value) {
47+
return this.props.setVariable(key, value);
48+
}
49+
4250
setInt(key, value) {
4351
return this.props.setInt(key, value);
4452
}
@@ -85,6 +93,10 @@ Widget.Settings = class extends React.Component {
8593
return this.widgetConfig
8694
}
8795

96+
getVariable(key) {
97+
return this.props.getVariable(key);
98+
}
99+
88100
getInt(key) {
89101
return this.props.getInt(key);
90102
}
@@ -101,6 +113,10 @@ Widget.Settings = class extends React.Component {
101113
return this.props.getBoolean(key);
102114
}
103115

116+
setVariable(key, value) {
117+
return this.props.setVariable(key, value);
118+
}
119+
104120
setInt(key, value) {
105121
return this.props.setInt(key, value);
106122
}

src/main/resources/static/javascript/widgets/double-editor.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ DoubleEditor.Body = class extends Widget.Body {
1818
}
1919

2020
settingsSave(newConfig) {
21-
this.removeVarListener(this.state.targetName);
21+
this.removeVarListener(this.state.targetName, this.callbackId);
2222
// do something with success, and also update event listener for variable changes
2323
let newValue = (this.getDouble(newConfig.variables.target) === undefined) ? '' : this.getDouble(newConfig.variables.target);
2424
this.setState({

src/main/resources/static/javascript/widgets/int-editor.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ IntEditor.Body = class extends Widget.Body {
1818
}
1919

2020
settingsSave(newConfig) {
21-
this.removeVarListener(this.state.targetName);
21+
this.removeVarListener(this.state.targetName, this.callbackId);
2222
let newValue = (this.getInt(newConfig.variables.target) === undefined) ? "" : this.getInt(newConfig.variables.target);
2323
this.setState({
2424
targetName: newConfig.variables.target,
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import PageUtils from 'page-utils';
2+
import Widget from 'widget';
3+
4+
class StringChooser {}
5+
6+
StringChooser.Body = class extends Widget.Body {
7+
init() {
8+
console.log(this.constructor.name)
9+
let newValue = (this.getVariable(this.widgetConfig.variables.target) === undefined) ? {options: [''], selected: ''} : this.getVariable(this.widgetConfig.variables.target);
10+
this.state = {
11+
targetName: this.widgetConfig.variables.target,
12+
targetValue: newValue
13+
};
14+
this.callbackId = this.registerVarListener(this.state.targetName, (key, value) => this.updateState(key, value));
15+
}
16+
17+
updateState(key, value) {
18+
this.setState({targetValue: value});
19+
}
20+
21+
settingsSave(newConfig) {
22+
this.removeVarListener(this.state.targetName, this.callbackId);
23+
// do something with success, and also update event listener for variable changes
24+
let newValue = (this.getString(newConfig.variables.target) === undefined) ? '' : this.getString(newConfig.variables.target);
25+
this.setState({
26+
targetName: newConfig.variables.target,
27+
targetValue: newValue
28+
});
29+
this.callbackId = this.registerVarListener(newConfig.variables.target, (key, value) => this.updateState(key, value));
30+
}
31+
32+
getOptions() {
33+
let options = [];
34+
for(let i in this.state.targetValue.options) {
35+
options.push(<a className="dropdown-item" onClick={() => this.updateSelectedValue(this.state.targetValue.options[i])} key={this.state.targetValue.options[i]} href="#">{this.state.targetValue.options[i]}</a>);
36+
}
37+
return options;
38+
}
39+
40+
updateSelectedValue(select) {
41+
let newValue = this.state.targetValue;
42+
newValue.selected = select;
43+
this.setState({targetValue: newValue});
44+
this.setVariable(this.state.targetName, newValue);
45+
}
46+
47+
render() {
48+
let buttonId = this.widgetConfig.id + "dropdownButton";
49+
return (
50+
<div className="dropdown show">
51+
<a className="btn btn-primary dropdown-toggle" href="#" role="button" id={buttonId} data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
52+
{this.state.targetValue.selected}
53+
</a>
54+
55+
<div className="dropdown-menu" aria-labelledby={buttonId}>
56+
{this.getOptions()}
57+
</div>
58+
</div>
59+
);
60+
}
61+
}
62+
63+
StringChooser.Settings = class extends Widget.Settings {
64+
init() {
65+
this.state = {
66+
targetName: this.widgetConfig.variables.target
67+
};
68+
}
69+
70+
settingsData(config) {
71+
let newConfig = config;
72+
newConfig.variables.target = this.state.targetName;
73+
return newConfig;
74+
}
75+
76+
onSettingsEdit(e) {
77+
this.setState({targetName: e.target.value});
78+
}
79+
80+
render() {
81+
return (
82+
<input className='form-control mb-2' type='text' placeholder='variable' value={this.state.targetName} onChange={(e) => this.onSettingsEdit(e)} />
83+
);
84+
}
85+
}
86+
87+
export default StringChooser;
88+
89+
// make sure to do this for every widget
90+
PageUtils.addWidgetClass('StringChooser', StringChooser);

0 commit comments

Comments
 (0)