Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xblock-vectordraw
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
xblock-vectordraw
Commits
d2fe0450
Commit
d2fe0450
authored
Nov 24, 2015
by
Tim Krones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make LMS and Studio functionality accessible.
parent
c3a098db
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
503 additions
and
27 deletions
+503
-27
tests/integration/test_vectordraw.py
+0
-0
tests/integration/xml/custom.xml
+1
-0
vectordraw/public/css/vectordraw.css
+36
-7
vectordraw/public/css/vectordraw_edit.css
+104
-0
vectordraw/public/js/vectordraw.js
+0
-0
vectordraw/public/js/vectordraw_edit.js
+158
-1
vectordraw/templates/html/vectordraw.html
+79
-19
vectordraw/templates/html/vectordraw_edit.html
+77
-0
vectordraw/vectordraw.py
+48
-0
No files found.
tests/integration/test_vectordraw.py
View file @
d2fe0450
This diff is collapsed.
Click to expand it.
tests/integration/xml/custom.xml
View file @
d2fe0450
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
vector_properties_label=
"Custom properties label"
vector_properties_label=
"Custom properties label"
background_url=
"https://github.com/open-craft/jsinput-vectordraw/raw/master/Notes_and_Examples/2_boxIncline_multiVector/box_on_incline.png"
background_url=
"https://github.com/open-craft/jsinput-vectordraw/raw/master/Notes_and_Examples/2_boxIncline_multiVector/box_on_incline.png"
background_width=
"20"
background_width=
"20"
background_description=
"A very informative description"
vectors=
"{{ vectors }}"
vectors=
"{{ vectors }}"
points=
"{{ points }}"
points=
"{{ points }}"
expected_result=
"{{ expected_result }}"
expected_result=
"{{ expected_result }}"
...
...
vectordraw/public/css/vectordraw.css
View file @
d2fe0450
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
pointer-events
:
none
;
/* prevents cursor from turning into caret when over a label */
pointer-events
:
none
;
/* prevents cursor from turning into caret when over a label */
}
}
/* Menu */
.vectordraw_block
.menu
{
.vectordraw_block
.menu
{
width
:
100%
;
width
:
100%
;
}
}
...
@@ -41,7 +43,7 @@
...
@@ -41,7 +43,7 @@
font-size
:
18px
;
font-size
:
18px
;
}
}
.vectordraw_block
.menu
.controls
button
{
.vectordraw_block
.menu
button
{
border
:
1px
solid
#1f628d
;
border
:
1px
solid
#1f628d
;
border-radius
:
5px
;
border-radius
:
5px
;
margin
:
4px
0
;
margin
:
4px
0
;
...
@@ -53,7 +55,7 @@
...
@@ -53,7 +55,7 @@
text-decoration
:
none
;
text-decoration
:
none
;
}
}
.vectordraw_block
.menu
.controls
button
:hover
{
.vectordraw_block
.menu
button
:hover
{
background
:
#c2e0f4
;
background
:
#c2e0f4
;
background-image
:
-webkit-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
background-image
:
-webkit-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
background-image
:
-moz-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
background-image
:
-moz-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
...
@@ -85,12 +87,39 @@
...
@@ -85,12 +87,39 @@
margin
:
0
0
5px
;
margin
:
0
0
5px
;
}
}
.vectordraw_block
.menu
.vector-properties
.vector-prop-bold
{
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
{
font-weight
:
bold
;
display
:
table
;
width
:
100%
}
}
.vectordraw_block
.menu
.vector-prop-slope
{
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
{
display
:
none
;
display
:
table-row
;
}
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-name
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-tail
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-tail-label
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-length
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-length-label
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-angle
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-angle-label
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-slope
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-slope-label
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-update
{
display
:
table-cell
;
width
:
50%
}
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-name
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-tail
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-angle
{
padding-right
:
5px
;
}
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
select
,
.vectordraw_block
.menu
.vector-properties
.vector-prop-list
.row
input
{
float
:
right
;
width
:
50%
;
}
}
.vectordraw_block
.action
button
{
.vectordraw_block
.action
button
{
...
@@ -101,7 +130,7 @@
...
@@ -101,7 +130,7 @@
}
}
/* Make sure screen-reader content is hidden in the workbench: */
/* Make sure screen-reader content is hidden in the workbench: */
.vectordraw_block
.
action
.
sr
{
.vectordraw_block
.sr
{
display
:
none
;
display
:
none
;
border
:
0
;
border
:
0
;
clip
:
rect
(
0
0
0
0
);
clip
:
rect
(
0
0
0
0
);
...
...
vectordraw/public/css/vectordraw_edit.css
View file @
d2fe0450
...
@@ -27,3 +27,107 @@
...
@@ -27,3 +27,107 @@
pointer-events
:
none
;
/* prevents cursor from turning into caret when over a label */
pointer-events
:
none
;
/* prevents cursor from turning into caret when over a label */
}
}
/* Menu */
.vectordraw_edit_block
.menu
{
width
:
100%
;
}
.vectordraw_edit_block
.menu
.controls
{
border-top-left-radius
:
5px
;
border-top-right-radius
:
5px
;
border-top
:
2px
solid
#1f628d
;
border-left
:
2px
solid
#1f628d
;
border-right
:
2px
solid
#1f628d
;
padding
:
3px
;
background-color
:
#e0e0e0
;
font-size
:
0
;
}
.vectordraw_edit_block
.menu
.controls
select
{
width
:
160px
;
margin-right
:
3px
;
font-size
:
18px
;
}
.vectordraw_edit_block
.menu
button
{
border
:
1px
solid
#1f628d
;
border-radius
:
5px
;
margin
:
4px
0
;
padding
:
5px
10px
5px
10px
;
box-shadow
:
0
1px
3px
#666
;
background-color
:
#c2e0f4
;
color
:
#1f628d
;
font-size
:
14px
;
text-decoration
:
none
;
}
.vectordraw_edit_block
.menu
button
:hover
{
background
:
#c2e0f4
;
background-image
:
-webkit-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
background-image
:
-moz-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
background-image
:
-ms-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
background-image
:
-o-linear-gradient
(
top
,
#c2e0f4
,
#add5f0
);
background-image
:
linear-gradient
(
to
bottom
,
#c2e0f4
,
#add5f0
);
text-decoration
:
none
;
}
.vectordraw_edit_block
.menu
.vector-properties
{
border-top
:
2px
solid
#1f628d
;
border-left
:
2px
solid
#1f628d
;
border-right
:
2px
solid
#1f628d
;
border-bottom
:
0px
none
;
padding
:
10px
;
font-size
:
16px
;
line-height
:
1.25
;
background-color
:
#f7f7f7
;
}
.vectordraw_edit_block
.menu
.vector-properties
h3
{
font-size
:
16px
;
margin
:
0
0
5px
;
}
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
{
display
:
table
;
width
:
100%
}
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
{
display
:
table-row
;
}
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-name
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-tail
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-tail-label
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-length
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-length-label
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-angle
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-angle-label
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-slope
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-slope-label
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-update
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-remove
{
display
:
table-cell
;
width
:
50%
}
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-name
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-tail
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-prop-angle
{
padding-right
:
5px
;
}
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
select
,
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
input
{
float
:
right
;
width
:
50%
;
}
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-remove
{
vertical-align
:
bottom
;
}
.vectordraw_edit_block
.menu
.vector-properties
.vector-prop-list
.row
.vector-remove
button
{
float
:
right
;
}
vectordraw/public/js/vectordraw.js
View file @
d2fe0450
This diff is collapsed.
Click to expand it.
vectordraw/public/js/vectordraw_edit.js
View file @
d2fe0450
This diff is collapsed.
Click to expand it.
vectordraw/templates/html/vectordraw.html
View file @
d2fe0450
...
@@ -10,9 +10,10 @@
...
@@ -10,9 +10,10 @@
{% endif %}
{% endif %}
<div
id=
"vectordraw"
>
<div
id=
"vectordraw"
>
<div
class=
"menu"
>
<div
class=
"menu"
style=
"width: {{ self.menu_width }}px;"
>
<div
class=
"controls"
>
<div
class=
"controls"
>
<select>
<span
class=
"sr"
id=
"element-list-add-label"
>
{% trans "Select element to add to board" %}
</span>
<select
class=
"element-list-add"
aria-labelledby=
"element-list-add-label"
>
{% for vector in self.get_vectors %}
{% for vector in self.get_vectors %}
<option
value=
"vector-{{ forloop.counter0 }}"
>
<option
value=
"vector-{{ forloop.counter0 }}"
>
{{ vector.description }}
{{ vector.description }}
...
@@ -29,29 +30,88 @@
...
@@ -29,29 +30,88 @@
<button
class=
"add-vector"
>
<button
class=
"add-vector"
>
{{ self.add_vector_label }}
{{ self.add_vector_label }}
</button>
</button>
<button
class=
"reset"
>
Reset
</button>
<button
class=
"reset"
>
<button
class=
"redo"
title=
"Redo"
><span
class=
"fa fa-repeat"
/></button>
<span
class=
"reset-label"
aria-hidden=
"true"
>
{% trans "Reset" %}
</span>
<button
class=
"undo"
title=
"Undo"
><span
class=
"fa fa-undo"
/></button>
<span
class=
"sr"
>
{% trans "Reset board to initial state" %}
</span>
</button>
<button
class=
"redo"
title=
"Redo"
>
<span
class=
"redo-label fa fa-repeat"
aria-hidden=
"true"
></span>
<span
class=
"sr"
>
{% trans "Redo last action" %}
</span>
</button>
<button
class=
"undo"
title=
"Undo"
>
<span
class=
"undo-label fa fa-undo"
aria-hidden=
"true"
></span>
<span
class=
"sr"
>
{% trans "Undo last action" %}
</span>
</button>
</div>
</div>
{% if self.show_vector_properties %}
{% if self.show_vector_properties %}
<div
class=
"vector-properties"
>
<div
class=
"vector-properties"
aria-live=
"polite"
>
<h3>
{{ self.vector_properties_label }}
</h3>
<h3>
{{ self.vector_properties_label }}
</h3>
<div
class=
"vector-prop-name"
>
<div
class=
"vector-prop-list"
>
{% trans "name" %}:
<span
class=
"value vector-prop-bold"
>
-
</span>
<div
class=
"row"
>
</div>
<div
class=
"vector-prop-name"
>
<div
class=
"vector-prop-length"
>
<span
id=
"vector-prop-name-label"
>
{% trans "length" %}:
<span
class=
"value"
>
-
</span>
{% trans "name" %}:
</div>
</span>
<div
class=
"vector-prop-angle"
>
<select
class=
"element-list-edit"
aria-labelledby=
"vector-prop-name-label"
>
{% trans "angle" %}:
<span
class=
"value"
>
-
</span>
°
<option
value=
"-"
selected=
"selected"
disabled=
"disabled"
>
-
</option>
</div>
{% for vector in self.get_vectors %}
<div
class=
"vector-prop-slope"
>
<option
value=
"vector-{{ forloop.counter0 }}"
data-vector-name=
"{{ vector.name }}"
>
{% trans "slope" %}:
<span
class=
"value"
>
-
</span>
{{ vector.name }}
</option>
{% endfor %}
{% for point in self.get_points %}
{% if not point.fixed %}
<option
value=
"point-{{ forloop.counter0 }}"
>
{{ point.name }}
</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div
class=
"row"
>
<div
class=
"vector-prop-tail"
>
<span
id=
"vector-prop-tail-label"
>
{% trans "tail position" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-tail-label"
>
</div>
<div
class=
"vector-prop-length"
>
<span
id=
"vector-prop-length-label"
>
{% trans "length" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-length-label"
>
</div>
</div>
<div
class=
"row"
>
<div
class=
"vector-prop-angle"
>
<span
id=
"vector-prop-angle-label"
>
{% trans "angle" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-angle-label"
>
</div>
<div
class=
"vector-prop-slope"
>
<span
id=
"vector-prop-slope-label"
>
{% trans "slope" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-slope-label"
disabled=
"disabled"
>
</div>
</div>
<div
class=
"row"
>
<div
class=
"vector-prop-update"
>
<button
class=
"update"
>
<span
class=
"update-label"
aria-hidden=
"true"
>
{% trans "Update" %}
</span>
<span
class=
"sr"
>
{% trans "Update properties of selected element" %}
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
<div
class=
"jxgboard"
style=
"width: {{ self.width }}px; height: {{ self.height }}px;"
></div>
<div
class=
"jxgboard"
style=
"width: {{ self.width }}px; height: {{ self.height }}px;"
aria-live=
"polite"
></div>
</div>
</div>
<div
class=
"vectordraw-status"
>
<div
class=
"vectordraw-status"
>
...
@@ -62,7 +122,7 @@
...
@@ -62,7 +122,7 @@
<div
class=
"action"
>
<div
class=
"action"
>
<button
class=
"check"
>
<button
class=
"check"
>
<span
class=
"check-label"
aria-hidden=
"true"
>
{% trans "Check" %}
</span>
<span
class=
"check-label"
aria-hidden=
"true"
>
{% trans "Check" %}
</span>
<span
class=
"sr"
>
{% trans "Check your answer" %}
</span>
<span
class=
"sr"
>
{% trans "Check your answer" %}
</span>
</button>
</button>
</div>
</div>
...
...
vectordraw/templates/html/vectordraw_edit.html
View file @
d2fe0450
...
@@ -73,14 +73,91 @@
...
@@ -73,14 +73,91 @@
To add a vector, left-click the board where you want the vector to originate.
To add a vector, left-click the board where you want the vector to originate.
Keep holding down the left mouse button and drag your mouse pointer across the board
Keep holding down the left mouse button and drag your mouse pointer across the board
to achieve the desired length and angle for the vector.
to achieve the desired length and angle for the vector.
Alternatively, you can click "Create vector", which will add a new vector
that starts at the center of the board and has a predefined length (3) and angle (90).
To modify an existing vector, left-click it, hold down the left mouse button,
To modify an existing vector, left-click it, hold down the left mouse button,
and move your mouse pointer across the board.
and move your mouse pointer across the board.
Alternatively, you can select an existing vector from the dropdown menu
modify its tail position, length, and angle by changing the values
in the corresponding input fields, and click "Update" to update its position on the board.
To remove an existing vector, left-click it or select it from the dropdown menu,
then click "Remove".
Note that if you make changes using the board below, any changes you made via the "Vectors" field above
Note that if you make changes using the board below, any changes you made via the "Vectors" field above
will be overwritten when you save the settings for this exercise by clicking the "Save" button below.
will be overwritten when you save the settings for this exercise by clicking the "Save" button below.
{% endblocktrans %}
{% endblocktrans %}
</p>
</p>
<div
id=
"vectordraw"
>
<div
id=
"vectordraw"
>
<div
class=
"menu"
style=
"width: {{ self.menu_width }}px;"
>
<div
class=
"controls"
>
<button
class=
"add-vector"
>
{% trans "Create vector" %}
</button>
</div>
<div
class=
"vector-properties"
aria-live=
"polite"
>
<h3>
{{ self.vector_properties_label }}
</h3>
<div
class=
"vector-prop-list"
>
<div
class=
"row"
>
<div
class=
"vector-prop-name"
>
<span
id=
"vector-prop-name-label"
>
{% trans "name" %}:
</span>
<select
class=
"element-list-edit"
aria-labelledby=
"vector-prop-name-label"
>
<option
value=
"-"
selected=
"selected"
disabled=
"disabled"
>
-
</option>
{% for vector in self.get_vectors %}
<option
value=
"vector-{{ forloop.counter0 }}"
data-vector-name=
"{{ vector.name }}"
>
{{ vector.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"row"
>
<div
class=
"vector-prop-tail"
>
<span
id=
"vector-prop-tail-label"
>
{% trans "tail position" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-tail-label"
>
</div>
<div
class=
"vector-prop-length"
>
<span
id=
"vector-prop-length-label"
>
{% trans "length" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-length-label"
>
</div>
</div>
<div
class=
"row"
>
<div
class=
"vector-prop-angle"
>
<span
id=
"vector-prop-angle-label"
>
{% trans "angle" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-angle-label"
>
</div>
<div
class=
"vector-prop-slope"
>
<span
id=
"vector-prop-slope-label"
>
{% trans "slope" %}:
</span>
<input
type=
"text"
value=
"-"
aria-labelledby=
"vector-prop-slope-label"
disabled=
"disabled"
>
</div>
</div>
<div
class=
"row"
>
<div
class=
"vector-prop-update"
>
<button
class=
"update"
>
<span
class=
"update-label"
aria-hidden=
"true"
>
{% trans "Update" %}
</span>
<span
class=
"sr"
>
{% trans "Update properties of selected element" %}
</span>
</button>
</div>
<div
class=
"vector-remove"
>
<button
class=
"remove"
>
<span
class=
"remove-label"
aria-hidden=
"true"
>
{% trans "Remove" %}
</span>
<span
class=
"sr"
>
{% trans "Remove selected element" %}
</span>
</button>
</div>
</div>
</div>
</div>
</div>
<div
class=
"jxgboard"
<div
class=
"jxgboard"
style=
"width: {{ self.width }}px; height: {{ self.height }}px;"
style=
"width: {{ self.width }}px; height: {{ self.height }}px;"
tabindex=
"0"
>
tabindex=
"0"
>
...
...
vectordraw/vectordraw.py
View file @
d2fe0450
...
@@ -7,6 +7,7 @@ from xblock.core import XBlock
...
@@ -7,6 +7,7 @@ from xblock.core import XBlock
from
xblock.exceptions
import
JsonHandlerError
from
xblock.exceptions
import
JsonHandlerError
from
xblock.fields
import
Scope
,
Boolean
,
Dict
,
Float
,
Integer
,
String
from
xblock.fields
import
Scope
,
Boolean
,
Dict
,
Float
,
Integer
,
String
from
xblock.fragment
import
Fragment
from
xblock.fragment
import
Fragment
from
xblock.validation
import
ValidationMessage
from
xblockutils.resources
import
ResourceLoader
from
xblockutils.resources
import
ResourceLoader
from
xblockutils.studio_editable
import
StudioEditableXBlockMixin
from
xblockutils.studio_editable
import
StudioEditableXBlockMixin
...
@@ -133,6 +134,17 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
...
@@ -133,6 +134,17 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
scope
=
Scope
.
content
scope
=
Scope
.
content
)
)
background_description
=
String
(
display_name
=
"Background description"
,
help
=
(
"Please provide a description of the image for non-visual users. "
"The description should provide sufficient information that would allow anyone "
"to solve the problem if the image did not load."
),
default
=
""
,
scope
=
Scope
.
content
)
vectors
=
String
(
vectors
=
String
(
display_name
=
"Vectors"
,
display_name
=
"Vectors"
,
help
=
(
help
=
(
...
@@ -218,6 +230,7 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
...
@@ -218,6 +230,7 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
'background_url'
,
'background_url'
,
'background_width'
,
'background_width'
,
'background_height'
,
'background_height'
,
'background_description'
,
'vectors'
,
'vectors'
,
'points'
,
'points'
,
'expected_result'
,
'expected_result'
,
...
@@ -251,6 +264,14 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
...
@@ -251,6 +264,14 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
}
}
@property
@property
def
menu_width
(
self
):
"""
Width of SVG canvas (controlled by JSXGraph) consistently ends up being 4px larger
than self.width. Adjust menu size accordingly to ensure that board and menu line up.
"""
return
self
.
width
+
4
@property
def
user_state
(
self
):
def
user_state
(
self
):
"""
"""
Return user state, which is a combination of most recent answer and result.
Return user state, which is a combination of most recent answer and result.
...
@@ -269,6 +290,7 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
...
@@ -269,6 +290,7 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
'src'
:
self
.
background_url
,
'src'
:
self
.
background_url
,
'width'
:
self
.
background_width
,
'width'
:
self
.
background_width
,
'height'
:
self
.
background_height
,
'height'
:
self
.
background_height
,
'description'
:
self
.
background_description
,
}
}
def
_get_default_vector
(
self
):
# pylint: disable=no-self-use
def
_get_default_vector
(
self
):
# pylint: disable=no-self-use
...
@@ -420,6 +442,32 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
...
@@ -420,6 +442,32 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
)
)
return
fragment
return
fragment
def
validate_field_data
(
self
,
validation
,
data
):
"""
Validate this block's field data.
"""
super
(
VectorDrawXBlock
,
self
)
.
validate_field_data
(
validation
,
data
)
def
add_error
(
msg
):
""" Helper function for adding validation messages. """
validation
.
add
(
ValidationMessage
(
ValidationMessage
.
ERROR
,
msg
))
if
data
.
background_url
.
strip
():
if
data
.
background_width
==
0
and
data
.
background_height
==
0
:
add_error
(
u"You specified a background image but no width or height. "
"For the image to display, you need to specify a non-zero value "
"for at least one of them."
)
if
not
data
.
background_description
.
strip
():
add_error
(
u"No background description set. "
"This means that it will be more difficult for non-visual users "
"to solve the problem. "
"Please provide a description that contains sufficient information "
"that would allow anyone to solve the problem if the image did not load."
)
def
_validate_check_answer_data
(
self
,
data
):
# pylint: disable=no-self-use
def
_validate_check_answer_data
(
self
,
data
):
# pylint: disable=no-self-use
"""
"""
Validate answer data submitted by user.
Validate answer data submitted by user.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment