Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cms/djangoapps/contentstore/views/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@

OPEN_ENDED_COMPONENT_TYPES = ["combinedopenended", "peergrading"]
NOTE_COMPONENT_TYPES = ['notes']
ADVANCED_COMPONENT_TYPES = ['annotatable', 'word_cloud', 'videoalpha'] + OPEN_ENDED_COMPONENT_TYPES + NOTE_COMPONENT_TYPES
ADVANCED_COMPONENT_TYPES = [
'annotatable',
'word_cloud',
'videoalpha',
'graphical_slider_tool'
] + OPEN_ENDED_COMPONENT_TYPES + NOTE_COMPONENT_TYPES
ADVANCED_COMPONENT_CATEGORY = 'advanced'
ADVANCED_COMPONENT_POLICY_KEY = 'advanced_modules'

Expand Down
44 changes: 44 additions & 0 deletions common/lib/xmodule/xmodule/css/gst/display.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// In the LMS sliders use built-in styles from jquery-ui-1.8.22.custom.css.
// CMS uses its own sliders styles.
// These styles we use only to sure, that slider in GST module
// will be render correctly (just like a duplication some from jquery-ui-1.8.22.custom.css).
// Cause, for example, CMS overwrites many jquery-ui-1.8.22.custom.css styles,
// and we must overwrite them again.

.ui-widget-content {
border: 1px solid #dddddd;
color: #333333;
}

.ui-widget {
font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
font-size: 1.1em;
}

.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl {
-moz-border-radius-topleft: 4px;
-webkit-border-top-left-radius: 4px;
-khtml-border-top-left-radius: 4px;
border-top-left-radius: 4px;
}

.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr {
-moz-border-radius-topright: 4px;
-webkit-border-top-right-radius: 4px;
-khtml-border-top-right-radius: 4px;
border-top-right-radius: 4px;
}

.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl {
-moz-border-radius-bottomleft: 4px;
-webkit-border-bottom-left-radius: 4px;
-khtml-border-bottom-left-radius: 4px;
border-bottom-left-radius: 4px;
}

.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br {
-moz-border-radius-bottomright: 4px;
-webkit-border-bottom-right-radius: 4px;
-khtml-border-bottom-right-radius: 4px;
border-bottom-right-radius: 4px;
}
137 changes: 77 additions & 60 deletions common/lib/xmodule/xmodule/gst_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@
from lxml import html
import xmltodict

from xmodule.mako_module import MakoModuleDescriptor
from xmodule.editing_module import XMLEditingDescriptor
from xmodule.xml_module import XmlDescriptor
from xmodule.x_module import XModule
from xmodule.stringify import stringify_children
from pkg_resources import resource_string
from xblock.core import String, Scope


log = logging.getLogger(__name__)

DEFAULT_RENDER="""
DEFAULT_RENDER = """
<h2>Graphic slider tool: Dynamic range and implicit functions.</h2>

<p>You can make the range of the x axis (but not ticks of x axis) of
Expand All @@ -33,13 +32,19 @@
</div>
<plot style="margin-top:15px;margin-bottom:15px;"/>
"""
DEFAULT_CONFIGURATION="""

DEFAULT_CONFIGURATION = """
<parameters>
<param var="r" min="5" max="25" step="0.5" initial="12.5" />
</parameters>
<functions>
<function color="red">Math.sqrt(r * r - x * x)</function>
<function color="red">-Math.sqrt(r * r - x * x)</function>
<function color="red">Math.sqrt(r * r / 20 - Math.pow(x-r/2.5, 2)) + r/8</function>
<function color="red">-Math.sqrt(r * r / 20 - Math.pow(x-r/2.5, 2)) + r/5.5</function>
<function color="red">Math.sqrt(r * r / 20 - Math.pow(x+r/2.5, 2)) + r/8</function>
<function color="red">-Math.sqrt(r * r / 20 - Math.pow(x+r/2.5, 2)) + r/5.5</function>
<function color="red">-Math.sqrt(r * r / 5 - x * x) - r/5.5</function>
</functions>
<plot>
<xrange>
Expand All @@ -54,51 +59,68 @@
"""



class GraphicalSliderToolFields(object):
render = String(scope=Scope.content, default=DEFAULT_RENDER)
configuration = String(scope=Scope.content, default=DEFAULT_CONFIGURATION)
data = String(
help="Html contents to display for this module",
default='<render>{}</render><configuration>{}</configuration>'.format(
DEFAULT_RENDER, DEFAULT_CONFIGURATION),
scope=Scope.content
)


class GraphicalSliderToolModule(GraphicalSliderToolFields, XModule):
''' Graphical-Slider-Tool Module
'''

js = {
'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee')],
'js': [
# 3rd party libraries used by graphic slider tool.
# TODO - where to store them - outside xmodule?
resource_string(__name__, 'js/src/graphical_slider_tool/gst_main.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/inputs.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/graph.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/el_output.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/g_label_el_output.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/gst.js')

]
'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee')],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than setting these here, I think it would be better to have something like:

@property
def configuration(self):
    return stringify_children(html.fromstring(self.data).xpath('configuration')[0])

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpennington, thanks for your suggestions. Done.

'js': [
# 3rd party libraries used by graphic slider tool.
# TODO - where to store them - outside xmodule?
resource_string(__name__, 'js/src/graphical_slider_tool/gst_main.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/inputs.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/graph.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/el_output.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/g_label_el_output.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/gst.js')
]
}
css = {'scss': [resource_string(__name__, 'css/gst/display.scss')]}
js_module_name = "GraphicalSliderTool"

@property
def configuration(self):
return stringify_children(
html.fromstring(self.data).xpath('configuration')[0]
)

@property
def render(self):
return stringify_children(
html.fromstring(self.data).xpath('render')[0]
)

def get_html(self):
""" Renders parameters to template. """

# these 3 will be used in class methods
self.html_id = self.location.html_id()
self.html_class = self.location.category

self.configuration_json = self.build_configuration_json()
params = {
'gst_html': self.substitute_controls(self.render),
'element_id': self.html_id,
'element_class': self.html_class,
'configuration_json': self.configuration_json
}
'gst_html': self.substitute_controls(self.render),
'element_id': self.html_id,
'element_class': self.html_class,
'configuration_json': self.configuration_json
}
content = self.system.render_template(
'graphical_slider_tool.html', params)
'graphical_slider_tool.html', params
)
return content

def substitute_controls(self, html_string):
Expand Down Expand Up @@ -126,9 +148,10 @@ def substitute_controls(self, html_string):
if plot_el:
plot_el = plot_el[0]
plot_el.getparent().replace(plot_el, html.fromstring(
plot_div.format(element_class=self.html_class,
element_id=self.html_id,
style=plot_el.get('style', ""))))
plot_div.format(
element_class=self.html_class,
element_id=self.html_id,
style=plot_el.get('style', ""))))

# substitute sliders
slider_div = '<div class="{element_class}_slider" \
Expand All @@ -139,10 +162,11 @@ def substitute_controls(self, html_string):
slider_els = xml.xpath('//slider')
for slider_el in slider_els:
slider_el.getparent().replace(slider_el, html.fromstring(
slider_div.format(element_class=self.html_class,
element_id=self.html_id,
var=slider_el.get('var', ""),
style=slider_el.get('style', ""))))
slider_div.format(
element_class=self.html_class,
element_id=self.html_id,
var=slider_el.get('var', ""),
style=slider_el.get('style', ""))))

# substitute inputs aka textboxes
input_div = '<input class="{element_class}_input" \
Expand All @@ -151,11 +175,12 @@ def substitute_controls(self, html_string):
input_els = xml.xpath('//textbox')
for input_index, input_el in enumerate(input_els):
input_el.getparent().replace(input_el, html.fromstring(
input_div.format(element_class=self.html_class,
element_id=self.html_id,
var=input_el.get('var', ""),
style=input_el.get('style', ""),
input_index=input_index)))
input_div.format(
element_class=self.html_class,
element_id=self.html_id,
var=input_el.get('var', ""),
style=input_el.get('style', ""),
input_index=input_index)))

return html.tostring(xml)

Expand All @@ -170,11 +195,13 @@ def build_configuration_json(self):
"""
# <root> added for interface compatibility with xmltodict.parse
# class added for javascript's part purposes
return json.dumps(xmltodict.parse('<root class="' + self.html_class +
'">' + self.configuration + '</root>'))
root = '<root class="{}">{}</root>'.format(
self.html_class,
self.configuration)
return json.dumps(xmltodict.parse(root))


class GraphicalSliderToolDescriptor(GraphicalSliderToolFields, MakoModuleDescriptor, XmlDescriptor):
class GraphicalSliderToolDescriptor(GraphicalSliderToolFields, XMLEditingDescriptor, XmlDescriptor):
module_class = GraphicalSliderToolModule

@classmethod
Expand Down Expand Up @@ -202,24 +229,14 @@ def definition_from_xml(cls, xml_object, system):
exactly one '{0}' tag".format(child))
# finished

def parse(k):
"""Assumes that xml_object has child k"""
return stringify_children(xml_object.xpath(k)[0])
return {
'render': parse('render'),
'configuration': parse('configuration')
}, []
'data': stringify_children(xml_object)
}, []

def definition_to_xml(self, resource_fs):
'''Return an xml element representing this definition.'''
xml_object = etree.Element('graphical_slider_tool')

def add_child(k):
child_str = '<{tag}>{body}</{tag}>'.format(tag=k, body=getattr(self, k))
child_node = etree.fromstring(child_str)
xml_object.append(child_node)

for child in ['render', 'configuration']:
add_child(child)

data = '<{tag}>{body}</{tag}>'.format(
tag='graphical_slider_tool',
body=self.data)
xml_object = etree.fromstring(data)
return xml_object
2 changes: 1 addition & 1 deletion common/lib/xmodule/xmodule/tests/test_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ def test_graphicslidertool_import(self):
render_string_from_sample_gst_xml = """
<slider var="a" style="width:400px;float:left;"/>\
<plot style="margin-top:15px;margin-bottom:15px;"/>""".strip()
self.assertEqual(gst_sample.render, render_string_from_sample_gst_xml)
self.assertIn(render_string_from_sample_gst_xml, gst_sample.data)

def test_word_cloud_import(self):
modulestore = XMLModuleStore(DATA_DIR, course_dirs=['word_cloud'])
Expand Down
1 change: 1 addition & 0 deletions common/templates/courseware_vendor_js.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<script type="text/javascript" src="${static.url('js/vendor/jquery.cookie.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/jquery.qtip.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/jquery.scrollTo-1.4.2-min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>

## codemirror
<link rel="stylesheet" href="${static.url('js/vendor/CodeMirror/codemirror.css')}" type="text/css" media="all" />
Expand Down