Commit 080e96fd by Valera Rozuvan Committed by Alexander Kryklia

Work in progress on GST.

parent 5990fa2e
......@@ -26,10 +26,10 @@ class GraphicalSliderToolModule(XModule):
js = {
'js': [
resource_string(__name__, 'js/src/graphical_slider_tool/gst_main.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/mod1.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/mod2.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/mod3.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/mod4.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/state.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/logme.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/general_methods.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/sliders.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/mod5.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/gst.js')
......@@ -128,7 +128,7 @@ class GraphicalSliderToolModule(XModule):
Simple variant: slider and plot controls are not inside any tag.
"""
#substitute plot
plot_div = '<div class="${element_class}_plot" id="${element_id}_plot" \
plot_div = '<div class="' + self.html_class + '_plot" id="' + self.html_id + '_plot" \
style="width: 600px; height: 600px; padding: 0px; position: relative;"> \
This is plot</div>'
html_string = html_string.replace('$plot$', plot_div)
......@@ -139,7 +139,7 @@ class GraphicalSliderToolModule(XModule):
sliders = [sliders]
vars = [x['@var'] for x in sliders]
slider_div = '<div class="{element_class}_slider" id="{element_id}_{var}" \
slider_div = '<div class="{element_class}_slider" id="{element_id}_slider_{var}" \
data-var="{var}">This is slider</div>'
for var in vars:
......@@ -155,7 +155,7 @@ class GraphicalSliderToolModule(XModule):
inputs = [inputs]
vars = [x['@var'] for x in inputs]
input_div = '<div class="{element_class}_input" id="{element_id}_{var}" \
input_div = '<div class="{element_class}_input" id="{element_id}_input_{var}" \
data-var="{var}">This is input</div>'
for var in vars:
......
......@@ -2,9 +2,16 @@
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('mod1', [], function () {
console.log('we are in the mod1 callback');
define('GeneralMethods', [], function () {
if (!String.prototype.trim) {
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
String.prototype.trim = function trim(str) {
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};
}
return {
'module_name': 'GeneralMethods',
'module_status': 'OK'
};
});
......
......@@ -2,11 +2,19 @@
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('GstMain', ['mod1', 'mod2', 'mod3', 'mod4'], function (mod1, mod2, mod3, mod4) {
define('GstMain', ['State', 'logme', 'GeneralMethods', 'Sliders'], function (State, logme, GeneralMethods, Sliders) {
logme(GeneralMethods);
return GstMain;
function GstMain(gstId) {
console.log('The DOM ID of the current GST element is ' + gstId);
var config, state;
config = JSON.parse($('#' + gstId + '_json').html()).root;
state = State(gstId, config);
Sliders(gstId, config, state);
}
});
......
// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('logme', [], function () {
var debugMode;
// debugMode can be one of the following:
//
// true - All messages passed to logme will be written to the internal
// browser console.
// false - Suppress all output to the internal browser console.
//
// Obviously, if anywhere there is a direct console.log() call, we can't do
// anything about it. That's why use logme() - it will allow to turn off
// the output of debug information with a single change to a variable.
debugMode = true;
return logme;
/*
* function: logme
*
* A helper function that provides logging facilities. We don't want
* to call console.log() directly, because sometimes it is not supported
* by the browser. Also when everything is routed through this function.
* the logging output can be easily turned off.
*
* logme() supports multiple parameters. Each parameter will be passed to
* console.log() function separately.
*
*/
function logme() {
var i;
if (
(typeof debugMode === 'undefined') ||
(debugMode !== true) ||
(typeof window.console === 'undefined')
) {
return;
}
for (i = 0; i < arguments.length; i++) {
window.console.log(arguments[i]);
}
} // End-of: function logme
});
// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('mod2', [], function () {
console.log('we are in the mod2 callback');
return {
'module_status': 'OK'
};
});
// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('mod3', ['mod5'], function (mod5) {
console.log('we are in the mod3 callback');
console.log('mod5 status: [' + mod5.module_status + '].');
return {
'module_status': 'OK'
};
});
// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('mod4', [], function () {
console.log('we are in the mod4 callback');
return {
'module_status': 'OK'
};
});
// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('Sliders', ['logme'], function (logme) {
return Sliders;
function Sliders(gstId, config, state) {
logme('We are inside Sliders function.');
logme('gstId: ' + gstId);
logme(config);
logme(state);
// We will go through all of the sliders. For each one, we will make a
// jQuery UI slider for it, attach "on change" events, and set it's
// state - initial value, max, and min parameters.
if ((typeof config.sliders !== 'undefined') &&
(typeof config.sliders.slider !== 'undefined')) {
if ($.isArray(config.sliders.slider)) {
// config.sliders.slider is an array
for (c1 = 0; c1 < config.sliders.slider.length; c1++) {
createSlider(config.sliders.slider[c1]);
}
} else if ($.isPlainObject(config.sliders.slider)) {
// config.sliders.slider is an object
createSlider(config.sliders.slider);
}
}
function createSlider(obj) {
var constName, constValue, rangeBlobs, valueMin, valueMax,
sliderDiv, sliderWidth;
// The name of the constant is obj['@var']. Multiple sliders and/or
// inputs can represent the same constant - therefore we will get
// the most recent const value from the state object. The range is
// a string composed of 3 blobs, separated by commas. The first
// blob is the min value for the slider, the third blob is the max
// value for the slider.
if (typeof obj['@var'] === 'undefined') {
return;
}
constName = obj['@var'];
constValue = state.getConstValue(constName);
if (constValue === undefined) {
constValue = 0;
}
if (typeof obj['@range'] !== 'string') {
valueMin = constValue - 10;
valueMax = constValue + 10;
} else {
rangeBlobs = obj['@range'].split(',');
// We must have gotten exactly 3 blobs (pieces) from the split.
if (rangeBlobs.length !== 3) {
valueMin = constValue - 10;
valueMax = constValue + 10;
} else {
// Get the first blob from the split string.
valueMin = parseFloat(rangeBlobs[0]);
if (isNaN(valueMin) === true) {
valueMin = constValue - 10;
}
// Get the third blob from the split string.
valueMax = parseFloat(rangeBlobs[2]);
if (isNaN(valueMax) === true) {
valueMax = constValue + 10;
}
// Logically, the min, value, and max should make sense.
// I.e. we will make sure that:
//
// min <= value <= max
//
// If this is not the case, we will set some defaults.
if ((valueMin > valueMax) ||
(valueMin > constValue) ||
(valueMax < constValue)) {
valueMin = constValue - 10;
valueMax = constValue + 10;
}
}
}
sliderDiv = $('#' + gstId + '_slider_' + constName);
// If a corresponding slider DIV for this constant does not exist,
// do not do anything.
if (sliderDiv.length === 0) {
return;
}
// The default slider width.
sliderWidth = 400;
logme('width: 0');
logme(obj['@width']);
if (typeof obj['@width'] === 'string') {
logme('width: 1');
if (isNaN(parseInt(obj['@width'], 10)) === false) {
logme('width: 2');
sliderWidth = parseInt(obj['@width'], 10);
}
}
// Set the new width to the slider.
sliderDiv.width(sliderWidth);
// Create a jQuery UI slider from the current DIV. We will set
// starting parameters, and will also attach a handler to update
// the state on the change event.
sliderDiv.slider({
'min': valueMin,
'max': valueMax,
'value': constValue,
'change': sliderOnChange
});
return;
function sliderOnChange(event, ui) {
state.setConstValue(constName, ui.value);
}
}
}
});
// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('State', ['logme'], function (logme) {
// Since there will be (can be) multiple GST on a page, and each will have
// a separate state, we will create a factory constructor function. The
// constructor will expect the ID of the DIV with the GST contents, and the
// configuration object (parsed from a JSON string). It will return and
// object containing methods to set and get the private state properties.
// This module defines and returns a factory constructor.
return State;
/*
* function: State
*
*
*/
function State(gstId, config) {
var constants, c1;
constants = {};
// We must go through all of the input, and slider elements and
// retrieve all of the available constants. These will be added to an
// object as it's properties.
//
// First we will go through all of the inputs.
if ((typeof config.inputs !== 'undefined') &&
(typeof config.inputs.input !== 'undefined')) {
if ($.isArray(config.inputs.input)) {
// config.inputs.input is an array
for (c1 = 0; c1 < config.inputs.input.length; c1++) {
addConstFromInput(config.inputs.input[c1]);
}
} else if ($.isPlainObject(config.inputs.input)) {
// config.inputs.input is an object
addConstFromInput(config.inputs.input);
}
}
// Now we will go through all of the sliders.
if ((typeof config.sliders !== 'undefined') &&
(typeof config.sliders.slider !== 'undefined')) {
if ($.isArray(config.sliders.slider)) {
// config.sliders.slider is an array
for (c1 = 0; c1 < config.sliders.slider.length; c1++) {
addConstFromSlider(config.sliders.slider[c1]);
}
} else if ($.isPlainObject(config.sliders.slider)) {
// config.sliders.slider is an object
addConstFromSlider(config.sliders.slider);
}
}
logme(constants);
// The constructor will return an object with methods to operate on
// it's private properties.
return {
'getConstValue': getConstValue,
'setConstValue': setConstValue
};
function getConstValue(constName) {
if (constants.hasOwnProperty(constName) === false) {
// If the name of the constant is not tracked by state, return an
// 'undefined' value.
return;
}
return constants[constName];
}
function setConstValue(constName, constValue) {
if (constants.hasOwnProperty(constName) === false) {
// If the name of the constant is not tracked by state, return an
// 'undefined' value.
return;
}
if (isNaN(parseFloat(constValue)) === true) {
// We are interested only in valid float values.
return;
}
constants[constName] = parseFloat(constValue);
logme('From setConstValue: new value for "' + constName + '" is ' + constValue);
}
function addConstFromInput(obj) {
var constName, constValue;
// The name of the constant is obj['@var']. The value (initial) of
// the constant is obj['@initial']. I have taken the word 'initial'
// into brackets, because multiple inputs and/or sliders can
// represent the state of a single constant.
if (typeof obj['@var'] === 'undefined') {
return;
}
constName = obj['@var'];
if (typeof obj['@initial'] === 'undefined') {
constValue = 0;
} else {
constValue = parseFloat(obj['@initial']);
if (isNaN(constValue) === true) {
constValue = 0;
}
}
constants[constName] = constValue;
}
function addConstFromSlider(obj) {
var constName, constValue, rangeBlobs;
// The name of the constant is obj['@var']. The value (initial) of
// the constant is the second blob of the 'range' parameter of the
// slider which is obj['@range']. Multiple sliders and/or inputs
// can represent the same constant - therefore 'initial' is in
// brackets. The range is a string composed of 3 blobs, separated
// by commas.
if (typeof obj['@var'] === 'undefined') {
return;
}
constName = obj['@var'];
if (typeof obj['@range'] !== 'string') {
constValue = 0;
} else {
rangeBlobs = obj['@range'].split(',');
// We must have gotten exactly 3 blobs (pieces) from the split.
if (rangeBlobs.length !== 3) {
constValue = 0;
} else {
// Get the second blob from the split string.
constValue = parseFloat(rangeBlobs[1]);
if (isNaN(constValue) === true) {
constValue = 0;
}
}
}
constants[constName] = constValue;
}
} // End-of: function State
});
// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
<div align="center" id="${element_id}" class="${element_class}">
<!-- xidden field to read configuration json from -->
<div class="${element_class}" id="${element_id}_json" style="hidden"
data-json="${configuration_json}"></div>
<!-- hidden field to read configuration json from -->
<div class="${element_class}" id="${element_id}_json" style="display: none;">
${configuration_json}
</div>
<!-- xidden field to read configuration json from -->
<div class="${element_class}" id="${element_id}_plot_code" style="hidden"
data-plot="${plot_code}"></div>
<!-- hidden field to read configuration json from -->
<div class="${element_class}" id="${element_id}_plot_code" style="display: none;">
${plot_code}
</div>
<!-- main xml with marked places for sliders, number and plots -->
<!-- main xml with marked places for sliders, numbers, and plot -->
${gst_html}
</div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment