Commit 9a9a3241 by Tim Krones

Allow to display and interact with exercises in the LMS.

parent 6cb67fc6
/* CSS for VectorDrawXBlock */
.vectordraw_block .count {
.vectordraw_block {
display: inline-block;
}
.vectordraw_block .jxgboard {
float: left;
border: 2px solid #1f628d;
}
.vectordraw_block .jxgboard .JXGtext {
pointer-events: none; /* prevents cursor from turning into caret when over a label */
}
.vectordraw_block .menu {
float: left;
width: 160px;
margin-left: 15px;
}
.vectordraw_block .menu .controls {
margin-bottom: 20px;
font-size: 0;
}
.vectordraw_block .menu .controls select {
width: 160px;
margin-bottom: 8px;
font-size: 18px;
}
.vectordraw_block .menu .controls button {
display: inline-block;
background-color: #3498db;
border-radius: 5px;
box-shadow: 0 1px 3px #666;
color: #fff;
font-size: 14px;
padding: 5px 10px 5px 10px;
margin: 4px 0;
border: 2px solid #1f628d;
text-decoration: none;
width: 160px;
}
.vectordraw_block .menu .controls button:hover {
background: #3cb0fd;
background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db);
background-image: -moz-linear-gradient(top, #3cb0fd, #3498db);
background-image: -ms-linear-gradient(top, #3cb0fd, #3498db);
background-image: -o-linear-gradient(top, #3cb0fd, #3498db);
background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
text-decoration: none;
}
vectordraw_block .menu .controls button.undo,
vectordraw_block .menu .controls button.redo {
width: 78px;
}
.vectordraw_block .menu .controls button.undo {
margin-right: 4px;
}
.vectordraw_block .menu .vector-properties {
padding: 10px;
border: 1px solid #1f628d;
font-size: 16px;
line-height: 1.25;
}
.vectordraw_block .menu .vector-properties h3 {
font-size: 16px;
margin: 0 0 5px;
}
.vectordraw_block .menu .vector-properties .vector-prop-bold {
font-weight: bold;
}
.vectordraw_block p {
cursor: pointer;
.vectordraw_block .menu .vector-prop-slope {
display: none;
}
<div class="vectordraw_block">
<p>VectorDrawXBlock: count is now
<span class='count'>{self.count}</span> (click me to increment).
</p>
<div id="vectordraw" />
</div>
"""TO-DO: Write a description of what this XBlock is."""
import json
import pkg_resources
from xblock.core import XBlock
from xblock.fields import Scope, Integer
from xblock.fields import Scope, Boolean, Integer, String
from xblock.fragment import Fragment
from xblockutils.resources import ResourceLoader
from xblockutils.studio_editable import StudioEditableXBlockMixin
class VectorDrawXBlock(XBlock):
loader = ResourceLoader(__name__)
class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
"""
TO-DO: document what your XBlock does.
"""
......@@ -21,6 +27,185 @@ class VectorDrawXBlock(XBlock):
help="A simple counter, to show something happening",
)
# Content
display_name = String(
display_name="Title (display name)",
help="Title to display",
default="Vector Drawing",
scope=Scope.content
)
width = Integer(
display_name="Width",
help="The width of the board in pixels",
default=550,
scope=Scope.content
)
height = Integer(
display_name="",
help="The height of the board in pixels",
default=400,
scope=Scope.content
)
bounding_box_size = Integer(
display_name="",
help=(
"Defines the bounding box height of the graph area. "
"The bounding box width is calculated from the width/height ratio."
),
default=10,
scope=Scope.content
)
axis = Boolean(
display_name="Show axis",
help="Show the graph axis",
default=False,
scope=Scope.content
)
show_navigation = Boolean(
display_name="Show navigation",
help="Show navigation arrows and zoom controls",
default=False,
scope=Scope.content
)
show_vector_properties = Boolean(
display_name="Show vector properties",
help="Show box detailing vector properties",
default=True,
scope=Scope.content
)
show_slope_for_lines = Boolean(
display_name="Show slope for lines",
help="If True, slope will be shown for line objects.",
default=False,
scope=Scope.content
)
add_vector_label = String(
display_name="Add vector label",
help="Label for button that allows to add vectors to the board",
default="Add Selected Force",
scope=Scope.content
)
vector_properties_label = String(
display_name="Vector properties label",
help="Label for box that displays vector properties",
default="Vector Properties",
scope=Scope.content
)
background_url = String(
display_name="Background URL",
help="URL for background image",
default="",
scope=Scope.content
)
background_width = Integer(
display_name="Background width",
help="Width of background image",
default=0,
scope=Scope.content
)
background_height = Integer(
display_name="Background height",
help="Height of background image",
default=0,
scope=Scope.content
)
vectors = String(
display_name="Vectors",
help=(
"List of vectors to use for the exercise. "
"You must specify it as an array of entries where each entry represents an individual vector."
),
default="[]",
multiline_editor=True,
resettable_editor=False,
scope=Scope.content
)
points = String(
display_name="Points",
help=(
"List of points to be drawn on the board for reference, or to be placed by the student."
"You must specify it as an array of entries where each entry represents an individual point."
),
default="[]",
multiline_editor=True,
resettable_editor=False,
scope=Scope.content
)
expected_result = String(
display_name="Expected result",
help=(
"Defines vector properties for grading. "
"Vectors omitted from this setting are ignored when grading."
),
default="{}",
multiline_editor=True,
resettable_editor=False,
scope=Scope.content
)
custom_checks = String(
display_name="Custom checks",
help=(
'List of custom checks to use for grading. '
'This is needed when grading is more complex and cannot be defined in terms of "Expected results" only.'
),
default="[]",
multiline_editor=True,
resettable_editor=False,
scope=Scope.content
)
editable_fields = (
'display_name',
'width',
'height',
'bounding_box_size',
'axis',
'show_navigation',
'show_vector_properties',
'show_slope_for_lines',
'add_vector_label',
'vector_properties_label',
'background_url',
'background_width',
'background_height',
'vectors',
'points',
'expected_result',
'custom_checks'
)
@property
def background(self):
return {
'src': self.background_url,
'width': self.background_width,
'height': self.background_height,
}
@property
def vectors_json(self):
return json.loads(self.vectors)
@property
def points_json(self):
return json.loads(self.points)
def resource_string(self, path):
"""Handy helper for getting resources from our kit."""
data = pkg_resources.resource_string(__name__, path)
......@@ -32,12 +217,29 @@ class VectorDrawXBlock(XBlock):
The primary view of the VectorDrawXBlock, shown to students
when viewing courses.
"""
html = self.resource_string("static/html/vectordraw.html")
frag = Fragment(html.format(self=self))
frag.add_css(self.resource_string("static/css/vectordraw.css"))
frag.add_javascript(self.resource_string("static/js/src/vectordraw.js"))
frag.initialize_js('VectorDrawXBlock')
return frag
fragment = Fragment()
fragment.add_content(loader.render_template('static/html/vectordraw.html', context))
fragment.add_css(self.resource_string('static/css/vectordraw.css'))
fragment.add_javascript_url("//cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.98/jsxgraphcore.js")
fragment.add_javascript(self.resource_string("static/js/src/vectordraw.js"))
fragment.initialize_js(
'VectorDrawXBlock',
{
'width': self.width,
'height': self.height,
'bounding_box_size': self.bounding_box_size,
'axis': self.axis,
'show_navigation': self.show_navigation,
'show_vector_properties': self.show_vector_properties,
'show_slope_for_lines': self.show_slope_for_lines,
'add_vector_label': self.add_vector_label,
'vector_properties_label': self.vector_properties_label,
'background': self.background,
'vectors': self.vectors_json,
'points': self.points_json,
}
)
return fragment
# TO-DO: change this handler to perform your own actions. You may need more
# than one handler, or you may not need any handlers at all.
......
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