Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx-platform
Commits
975fc649
Commit
975fc649
authored
Dec 21, 2011
by
Piotr Mitros
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
UI Revamp step 1
parent
026eaa08
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
594 additions
and
151 deletions
+594
-151
courseware/static/css/images/css/topBanner.jpg
+0
-0
courseware/static/css/theme.css
+20
-6
courseware/static/js/schematic.js
+574
-145
No files found.
courseware/static/css/images/css/topBanner.jpg
View replaced file @
026eaa08
View file @
975fc649
17.6 KB
|
W:
|
H:
16 KB
|
W:
|
H:
2-up
Swipe
Onion skin
courseware/static/css/theme.css
View file @
975fc649
...
@@ -7,6 +7,20 @@ Copyright 2010 - Thierry Ruiz - www.dotemplate.com - All rights reserved.
...
@@ -7,6 +7,20 @@ Copyright 2010 - Thierry Ruiz - www.dotemplate.com - All rights reserved.
THIS TEMPLATE IS FREE AS LONG AS YOU KEEP THE LINK TO WWW.DOTEMPLATE.COM IN THE FOOTER
THIS TEMPLATE IS FREE AS LONG AS YOU KEEP THE LINK TO WWW.DOTEMPLATE.COM IN THE FOOTER
TO REMOVE THE LINK, PLEASE MAKE A 10 DOLLARS DONATION at www.dotemplate.com/#donate
TO REMOVE THE LINK, PLEASE MAKE A 10 DOLLARS DONATION at www.dotemplate.com/#donate
pmitros donated $10
Colors:
Light blue: bddeff
Blue: 7fbcfd
Very dark blue: #031634
Dark blue: #023063;
Dark Greenish: #7a994c;
Greenish: #adcc80;
Very light greenish: #dae5c9;
Bright orange: #fa720a;
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
*/
*/
...
@@ -27,10 +41,10 @@ body {
...
@@ -27,10 +41,10 @@ body {
}
}
body
{
body
{
color
:
#023063
;
color
:
#023063
;
font-family
:
Helvetica
,
Arial
,
sans-serif
;
font-family
:
Helvetica
,
Arial
,
sans-serif
;
font-size
:
12px
;
font-size
:
0.8em
;
font-style
:
normal
;
font-style
:
normal
;
font-weight
:
normal
;
font-weight
:
normal
;
text-transform
:
normal
;
text-transform
:
normal
;
...
@@ -43,7 +57,7 @@ p {
...
@@ -43,7 +57,7 @@ p {
h1
{
h1
{
color
:
#adcc80
;
color
:
#adcc80
;
font-size
:
24px
;
font-size
:
1.6em
;
margin
:
25px
0
10px
0
;
margin
:
25px
0
10px
0
;
clear
:
both
;
clear
:
both
;
}
}
...
@@ -51,7 +65,7 @@ h1 {
...
@@ -51,7 +65,7 @@ h1 {
h2
{
h2
{
color
:
#adcc80
;
color
:
#adcc80
;
font-size
:
1
8px
;
font-size
:
1
.1em
;
margin
:
20px
0
10px
0
;
margin
:
20px
0
10px
0
;
clear
:
both
;
clear
:
both
;
}
}
...
@@ -59,7 +73,7 @@ h2 {
...
@@ -59,7 +73,7 @@ h2 {
h3
{
h3
{
color
:
#adcc80
;
color
:
#adcc80
;
font-size
:
1
6px
;
font-size
:
1
em
;
margin
:
20px
0
5px
0
;
margin
:
20px
0
5px
0
;
clear
:
both
;
clear
:
both
;
}
}
...
@@ -139,7 +153,7 @@ a:hover {
...
@@ -139,7 +153,7 @@ a:hover {
position
:
relative
;
position
:
relative
;
height
:
20px
;
height
:
20px
;
text-transform
:
uppercase
;
text-transform
:
uppercase
;
font-size
:
12px
;
font-size
:
0.9em
;
font-family
:
Arial
,
sans-serif
;
font-family
:
Arial
,
sans-serif
;
}
}
...
...
courseware/static/js/schematic.js
View file @
975fc649
...
@@ -15,29 +15,30 @@
...
@@ -15,29 +15,30 @@
// height -- height in pixels of diagram
// height -- height in pixels of diagram
// parts -- comma-separated list of parts for parts bin (see parts_map)
// parts -- comma-separated list of parts for parts bin (see parts_map)
// JSON schematic representation:
// sch := [part, part, ...]
// part := [type, coords, properties, connections]
// type := string (see parts_map)
// coords := [number, ...] // (x,y,rot) or (x1,y1,x2,y2)
// properties := {name: value, ...}
// connections := [node, ...] // one per connection point in canoncial order
// node := string
// TO DO:
// TO DO:
// - read initial diagram from value of hidden input field
// - draggable overlay window base class (dialogs, scope, ...)
// - write diagram state into value of hidden input field
// - wire labels?
// - wire labels?
// - devices: diode, nfet, pfet, opamp, scope probe
// - devices: diode, nfet, pfet, opamp, scope probe
// - icons for test equipment? (scope, sig gen, counter, ...)
// - icons for test equipment? (scope, sig gen, counter, ...)
// - zoom/scroll canvas
// - freeze_diagram, freeze_properties attributes (freeze certain components/properties?)
// - rotate multiple objects around their center of mass
// - rotate multiple objects around their center of mass
// - rubber band wires when moving components
// - rubber band wires when moving components
// - add help messages/tooltips
// - tool bar (zoom in/zoom out, rotate, mode: wire/select, save/restore, simulate, help)
// - scroll canvas
// - freeze_diagram, freeze_properties attributes (freeze certain components/properties?)
// - add thumb to resize work area
// - label nodes, extract component netlist
// - simulation: operating points, trans, ac analysis, sweeps?
// - simulation: operating points, trans, ac analysis, sweeps?
// - how to integrate plot display?
// add ourselves to the tasks that get performed when window is loaded
window
.
onload
=
add_schematic_handler
(
window
.
onload
);
// set up each schematic entry widget
function
update_schematics
()
{
function
update_schematics
()
{
// set up each schematic on the page
// set up each schematic on the page
var
schematics
=
document
.
getElementsByClassName
(
'schematic'
);
var
schematics
=
document
.
getElementsByClassName
(
'schematic'
);
...
@@ -48,6 +49,7 @@ function update_schematics() {
...
@@ -48,6 +49,7 @@ function update_schematics() {
}
}
}
}
// add ourselves to the tasks that get performed when window is loaded
function
add_schematic_handler
(
other_onload
)
{
function
add_schematic_handler
(
other_onload
)
{
return
function
()
{
return
function
()
{
// execute othe onload functions first
// execute othe onload functions first
...
@@ -56,20 +58,29 @@ function add_schematic_handler(other_onload) {
...
@@ -56,20 +58,29 @@ function add_schematic_handler(other_onload) {
update_schematics
();
update_schematics
();
}
}
}
}
window
.
onload
=
add_schematic_handler
(
window
.
onload
);
background_style
=
'rgb(2
00,255,20
0)'
;
background_style
=
'rgb(2
20,220,22
0)'
;
element_style
=
'rgb(255,255,255)'
;
element_style
=
'rgb(255,255,255)'
;
thumb_style
=
'rgb(128,128,128)'
;
normal_style
=
'rgb(0,0,0)'
;
// color for unselected components
selected_style
=
'rgb(64,255,64)'
;
// highlight color for selected components
grid_style
=
"rgb(128,128,128)"
;
// list of all the defined parts
// list of all the defined parts
parts_map
=
{
parts_map
=
{
'g'
:
Ground
,
'g'
:
[
Ground
,
'Ground connection'
]
,
'v'
:
VSource
,
'v'
:
[
VSource
,
'Voltage source'
]
,
'i'
:
ISource
,
'i'
:
[
ISource
,
'Current source'
]
,
'r'
:
Resistor
,
'r'
:
[
Resistor
,
'Resistor'
]
,
'c'
:
Capacitor
,
'c'
:
[
Capacitor
,
'Capacitor'
]
,
'l'
:
Inductor
,
'l'
:
[
Inductor
,
'Inductor'
]
,
};
};
// fix cursor bug in Chrome (default behavior: change to text cursor
// whenever a drag is initiated).
document
.
onselectstart
=
function
()
{
return
false
;
};
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
//
// Schematic = diagram + parts bin + status area
// Schematic = diagram + parts bin + status area
...
@@ -78,29 +89,30 @@ parts_map = {
...
@@ -78,29 +89,30 @@ parts_map = {
// setup a schematic by populating the <div> with the appropriate children
// setup a schematic by populating the <div> with the appropriate children
function
Schematic
(
input
)
{
function
Schematic
(
input
)
{
var
div
=
document
.
createElement
(
'div'
);
this
.
div
=
document
.
createElement
(
'div'
);
// set up div so we can position elements inside of it
// set up div so we can position elements inside of it
div
.
style
.
position
=
'relative'
;
this
.
div
.
style
.
position
=
'relative'
;
this
.
div
.
style
.
cursor
=
'default'
;
// grab attributes from the <div> that created us
this
.
div
=
div
;
this
.
grid
=
8
;
this
.
grid
=
8
;
this
.
scale
=
2
;
this
.
scale
=
2
;
this
.
origin_x
=
0
;
this
.
origin_x
=
0
;
this
.
origin_y
=
0
;
this
.
origin_y
=
0
;
this
.
clipboard
=
null
;
// start with a background element with normal positioning
// start with a background element with normal positioning
this
.
background
=
document
.
createElement
(
'canvas'
);
this
.
background
=
document
.
createElement
(
'canvas'
);
this
.
background
.
style
.
backgroundColor
=
background_style
;
this
.
background
.
style
.
backgroundColor
=
background_style
;
this
.
background
.
style
.
borderStyle
=
'solid'
;
this
.
background
.
style
.
borderWidth
=
'2px'
;
this
.
status_div
=
document
.
createElement
(
'div'
);
this
.
status_div
=
document
.
createElement
(
'div'
);
this
.
status_div
.
style
.
borderStyle
=
'solid'
;
//
this.status_div.style.borderStyle = 'solid';
this
.
status_div
.
style
.
borderWidth
=
'1px'
;
//
this.status_div.style.borderWidth = '1px';
this
.
status_div
.
style
.
position
=
'absolute'
;
this
.
status_div
.
style
.
position
=
'absolute'
;
this
.
status_div
.
style
.
padding
=
'2px'
;
this
.
status_div
.
style
.
padding
=
'2px'
;
this
.
status_div
.
style
.
backgroundColor
=
element_style
;
//
this.status_div.style.backgroundColor = element_style;
this
.
status
=
document
.
createTextNode
(
'
Ready.
'
);
this
.
status
=
document
.
createTextNode
(
''
);
this
.
status_div
.
appendChild
(
this
.
status
);
this
.
status_div
.
appendChild
(
this
.
status
);
this
.
connection_points
=
new
Array
();
// location string => list of cp's
this
.
connection_points
=
new
Array
();
// location string => list of cp's
...
@@ -111,17 +123,26 @@ function Schematic(input) {
...
@@ -111,17 +123,26 @@ function Schematic(input) {
this
.
canvas
.
tabIndex
=
1
;
// so we get keystrokes
this
.
canvas
.
tabIndex
=
1
;
// so we get keystrokes
this
.
canvas
.
style
.
borderStyle
=
'solid'
;
this
.
canvas
.
style
.
borderStyle
=
'solid'
;
this
.
canvas
.
style
.
borderWidth
=
'1px'
;
this
.
canvas
.
style
.
borderWidth
=
'1px'
;
this
.
canvas
.
style
.
borderColor
=
grid_style
;
this
.
canvas
.
style
.
position
=
'absolute'
;
this
.
canvas
.
style
.
position
=
'absolute'
;
this
.
canvas
.
style
.
outline
=
'none'
;
this
.
canvas
.
schematic
=
this
;
this
.
canvas
.
schematic
=
this
;
this
.
canvas
.
addEventListener
(
'mousemove'
,
this
.
mouse_move
,
false
);
this
.
canvas
.
addEventListener
(
'mousemove'
,
schematic_mouse_move
,
false
);
this
.
canvas
.
addEventListener
(
'mouseover'
,
this
.
mouse_enter
,
false
);
this
.
canvas
.
addEventListener
(
'mouseover'
,
schematic_mouse_enter
,
false
);
this
.
canvas
.
addEventListener
(
'mouseout'
,
this
.
mouse_leave
,
false
);
this
.
canvas
.
addEventListener
(
'mouseout'
,
schematic_mouse_leave
,
false
);
this
.
canvas
.
addEventListener
(
'mousedown'
,
this
.
mouse_down
,
false
);
this
.
canvas
.
addEventListener
(
'mousedown'
,
schematic_mouse_down
,
false
);
this
.
canvas
.
addEventListener
(
'mouseup'
,
this
.
mouse_up
,
false
);
this
.
canvas
.
addEventListener
(
'mouseup'
,
schematic_mouse_up
,
false
);
this
.
canvas
.
addEventListener
(
'dblclick'
,
this
.
double_click
,
false
);
this
.
canvas
.
addEventListener
(
'dblclick'
,
schematic_double_click
,
false
);
this
.
canvas
.
addEventListener
(
'keydown'
,
this
.
key_down
,
false
);
this
.
canvas
.
addEventListener
(
'keydown'
,
schematic_key_down
,
false
);
this
.
canvas
.
addEventListener
(
'keypress'
,
this
.
key_press
,
false
);
this
.
canvas
.
addEventListener
(
'keypress'
,
schematic_key_press
,
false
);
// toolbar
this
.
tools
=
new
Array
();
this
.
toolbar
=
[];
this
.
tools
[
'cut'
]
=
this
.
add_tool
(
cut_icon
,
'Cut: move selected components from diagram to the clipboard'
,
this
.
cut
);
this
.
tools
[
'copy'
]
=
this
.
add_tool
(
copy_icon
,
'Copy: copy selected components into the clipboard'
,
this
.
copy
);
this
.
tools
[
'paste'
]
=
this
.
add_tool
(
paste_icon
,
'Paste: copy clipboard into the diagram'
,
this
.
paste
);
// make the canvas "clickable" by registering a dummy click handler
// make the canvas "clickable" by registering a dummy click handler
// this should make things work on the iPad
// this should make things work on the iPad
...
@@ -153,17 +174,20 @@ function Schematic(input) {
...
@@ -153,17 +174,20 @@ function Schematic(input) {
this
.
parts_bin
=
[];
this
.
parts_bin
=
[];
for
(
var
i
=
0
;
i
<
parts
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
parts
.
length
;
i
++
)
{
var
part
=
new
Part
(
this
);
var
part
=
new
Part
(
this
);
part
.
set_component
(
new
parts_map
[
parts
[
i
]](
part
,
0
,
0
,
0
));
var
pm
=
parts_map
[
parts
[
i
]];
part
.
set_component
(
new
pm
[
0
](
part
,
0
,
0
,
0
),
pm
[
1
]);
this
.
parts_bin
.
push
(
part
);
this
.
parts_bin
.
push
(
part
);
}
}
// add all elements to the DOM
// add all elements to the DOM
div
.
appendChild
(
this
.
background
);
this
.
div
.
appendChild
(
this
.
background
);
div
.
appendChild
(
this
.
canvas
);
for
(
var
i
=
0
;
i
<
this
.
toolbar
.
length
;
i
++
)
div
.
appendChild
(
this
.
status_div
);
this
.
div
.
appendChild
(
this
.
toolbar
[
i
]);
this
.
div
.
appendChild
(
this
.
canvas
);
this
.
div
.
appendChild
(
this
.
status_div
);
for
(
var
i
=
0
;
i
<
this
.
parts_bin
.
length
;
i
++
)
for
(
var
i
=
0
;
i
<
this
.
parts_bin
.
length
;
i
++
)
div
.
appendChild
(
this
.
parts_bin
[
i
].
canvas
);
this
.
div
.
appendChild
(
this
.
parts_bin
[
i
].
canvas
);
input
.
parentNode
.
insertBefore
(
div
,
input
.
nextSibling
);
input
.
parentNode
.
insertBefore
(
this
.
div
,
input
.
nextSibling
);
// make sure other code can find us!
// make sure other code can find us!
input
.
schematic
=
this
;
input
.
schematic
=
this
;
...
@@ -173,13 +197,56 @@ function Schematic(input) {
...
@@ -173,13 +197,56 @@ function Schematic(input) {
var
w
=
parseInt
(
input
.
getAttribute
(
'width'
));
var
w
=
parseInt
(
input
.
getAttribute
(
'width'
));
var
h
=
parseInt
(
input
.
getAttribute
(
'height'
));
var
h
=
parseInt
(
input
.
getAttribute
(
'height'
));
this
.
set_locations
(
w
,
h
);
this
.
set_locations
(
w
,
h
);
// process initial contents of diagram
this
.
load_schematic
(
this
.
input
.
value
);
}
Schematic
.
prototype
.
load_schematic
=
function
(
value
)
{
if
(
value
)
{
// convert string value into data structure
var
json
=
JSON
.
parse
(
value
);
// top level is a list of components
for
(
var
i
=
json
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
c
=
json
[
i
];
if
(
c
[
0
]
==
'view'
)
{
// special hack: view component lets us recreate view
this
.
origin_x
=
c
[
1
];
this
.
origin_y
=
c
[
2
];
this
.
scale
=
c
[
3
];
}
else
if
(
c
[
0
]
==
'w'
)
{
// wire
this
.
add_wire
(
c
[
1
][
0
],
c
[
1
][
1
],
c
[
1
][
2
],
c
[
1
][
3
]);
}
else
{
// ordinary component
// c := [type, coords, properties, connections]
var
type
=
c
[
0
];
var
coords
=
c
[
1
];
var
properties
=
c
[
2
];
// make the part
var
part
=
new
parts_map
[
type
][
0
](
this
,
coords
[
0
],
coords
[
1
],
coords
[
2
]);
// give it its properties
for
(
var
name
in
properties
)
part
.
properties
[
name
]
=
properties
[
name
];
// add component to the diagram
this
.
add_component
(
part
);
}
}
// see what we've got!
this
.
redraw_background
();
}
}
}
background_margin
=
5
;
background_margin
=
5
;
part_w
=
56
;
// size of a parts bin compartment
part_w
=
42
;
// size of a parts bin compartment
part_h
=
56
;
part_h
=
42
;
status_height
=
18
;
status_height
=
18
;
thumb_style
=
'rgb(128,128,128)'
;
// w,h are the dimensions of the canvas, everyone else is positioned accordingly
// w,h are the dimensions of the canvas, everyone else is positioned accordingly
Schematic
.
prototype
.
set_locations
=
function
(
w
,
h
)
{
Schematic
.
prototype
.
set_locations
=
function
(
w
,
h
)
{
...
@@ -197,33 +264,48 @@ Schematic.prototype.set_locations = function(w,h) {
...
@@ -197,33 +264,48 @@ Schematic.prototype.set_locations = function(w,h) {
this
.
max_x
=
w
/
this
.
scale
;
this
.
max_x
=
w
/
this
.
scale
;
this
.
max_y
=
h
/
this
.
scale
;
this
.
max_y
=
h
/
this
.
scale
;
var
left
=
2
*
background_margin
;
// space to the left
// start with tool bar
var
top
=
background_margin
;
if
(
this
.
toolbar
.
length
>
0
)
{
tool_left
=
left
;
for
(
var
i
=
0
;
i
<
this
.
toolbar
.
length
;
i
++
)
{
var
img
=
this
.
toolbar
[
i
];
img
.
style
.
left
=
tool_left
+
'px'
;
img
.
style
.
top
=
top
+
'px'
;
tool_left
+=
24
;
// width + 2*padding + 2*border + gap
}
top
+=
27
;
// height + 2*padding + 2*border + gap;
}
// configure canvas
// configure canvas
this
.
canvas
.
style
.
left
=
background_margin
+
'px'
;
this
.
canvas
.
style
.
left
=
left
+
'px'
;
this
.
canvas
.
style
.
top
=
background_margin
+
'px'
;
this
.
canvas
.
style
.
top
=
top
+
'px'
;
this
.
canvas
.
width
=
w
;
this
.
canvas
.
width
=
w
;
this
.
canvas
.
height
=
h
;
this
.
canvas
.
height
=
h
;
this
.
redraw_background
();
// redraw diagram
this
.
redraw_background
();
// redraw diagram
// configure status bar
// configure status bar
this
.
status_div
.
style
.
left
=
background_margin
+
'px'
;
this
.
status_div
.
style
.
left
=
left
+
'px'
;
this
.
status_div
.
style
.
top
=
this
.
canvas
.
offsetTop
+
this
.
canvas
.
offsetHeight
+
3
+
'px'
;
this
.
status_div
.
style
.
top
=
this
.
canvas
.
offsetTop
+
this
.
canvas
.
offsetHeight
+
3
+
'px'
;
this
.
status_div
.
style
.
width
=
(
w
-
4
)
+
'px'
;
// subtract interior padding
this
.
status_div
.
style
.
width
=
(
w
-
4
)
+
'px'
;
// subtract interior padding
this
.
status_div
.
style
.
height
=
status_height
+
'px'
;
this
.
status_div
.
style
.
height
=
status_height
+
'px'
;
// configure parts bin
// configure parts bin
var
total_w
=
this
.
canvas
.
offsetLeft
+
this
.
canvas
.
offsetWidth
;
var
total_w
=
this
.
canvas
.
offsetLeft
+
this
.
canvas
.
offsetWidth
;
var
parts_left
=
total_w
+
3
;
var
parts_left
=
total_w
+
5
;
var
parts_top
=
background_margin
;
var
parts_top
=
top
;
var
parts_h_limit
=
this
.
canvas
.
offsetTop
+
this
.
canvas
.
offsetHeight
;
var
parts_h_limit
=
this
.
canvas
.
offsetTop
+
this
.
canvas
.
offsetHeight
;
for
(
var
i
=
0
;
i
<
this
.
parts_bin
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
this
.
parts_bin
.
length
;
i
++
)
{
var
part
=
this
.
parts_bin
[
i
];
var
part
=
this
.
parts_bin
[
i
];
part
.
set_location
(
parts_left
,
parts_top
);
part
.
set_location
(
parts_left
,
parts_top
);
total_w
=
part
.
right
();
total_w
=
part
.
right
();
parts_top
=
part
.
bottom
()
-
1
;
parts_top
=
part
.
bottom
()
+
2
;
if
(
parts_top
+
part_h
>
parts_h_limit
)
{
if
(
parts_top
+
part_h
>
parts_h_limit
)
{
parts_left
=
total_w
-
1
;
parts_left
=
total_w
-
1
;
parts_top
=
background_margin
;
parts_top
=
top
;
}
}
}
}
...
@@ -249,10 +331,63 @@ Schematic.prototype.set_locations = function(w,h) {
...
@@ -249,10 +331,63 @@ Schematic.prototype.set_locations = function(w,h) {
*/
*/
}
}
// label all the nodes in the circuit
Schematic
.
prototype
.
label_connection_points
=
function
()
{
// start by clearing all the connection point labels
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
this
.
components
[
i
].
clear_labels
();
// components are in charge of labeling their unlabeled connections.
// labels given to connection points will propagate to coincident connection
// points and across Wires.
// let special components like GND label their connection(s)
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
this
.
components
[
i
].
add_default_labels
();
// now have components generate labels for unlabeled connections
this
.
next_label
=
0
;
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
this
.
components
[
i
].
label_connections
();
}
// generate a new label
Schematic
.
prototype
.
get_next_label
=
function
()
{
// generate next label in sequence
this
.
next_label
+=
1
;
return
this
.
next_label
.
toString
();
}
// propagate label to coincident connection points
Schematic
.
prototype
.
propagate_label
=
function
(
label
,
location
)
{
var
cplist
=
this
.
connection_points
[
location
];
for
(
var
i
=
cplist
.
length
-
1
;
i
>=
0
;
--
i
)
cplist
[
i
].
propagate_label
(
label
);
}
// update the value field of our corresponding input field with JSON
// update the value field of our corresponding input field with JSON
// representation of schematic
// representation of schematic
Schematic
.
prototype
.
update_value
=
function
()
{
Schematic
.
prototype
.
update_value
=
function
()
{
// to do: fill in this.input.value
// label connection points
this
.
label_connection_points
();
// build JSON data structure, convert to string value for
// input field
this
.
input
.
value
=
JSON
.
stringify
(
this
.
json
());
}
// produce a JSON representation of the diagram
Schematic
.
prototype
.
json
=
function
()
{
var
json
=
[];
// output all the components/wires in the diagram
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
json
.
push
(
this
.
components
[
i
].
json
());
// capture the current view parameters
json
.
push
([
'view'
,
this
.
origin_x
,
this
.
origin_y
,
this
.
scale
]);
return
json
;
}
}
Schematic
.
prototype
.
add_component
=
function
(
new_c
)
{
Schematic
.
prototype
.
add_component
=
function
(
new_c
)
{
...
@@ -268,7 +403,7 @@ Schematic.prototype.remove_component = function(c) {
...
@@ -268,7 +403,7 @@ Schematic.prototype.remove_component = function(c) {
// add connection point to list of connection points at that location
// add connection point to list of connection points at that location
Schematic
.
prototype
.
add_connection_point
=
function
(
cp
)
{
Schematic
.
prototype
.
add_connection_point
=
function
(
cp
)
{
cplist
=
this
.
connection_points
[
cp
.
location
]
var
cplist
=
this
.
connection_points
[
cp
.
location
];
if
(
cplist
)
cplist
.
push
(
cp
);
if
(
cplist
)
cplist
.
push
(
cp
);
else
{
else
{
cplist
=
[
cp
];
cplist
=
[
cp
];
...
@@ -332,6 +467,90 @@ Schematic.prototype.check_wires = function(c) {
...
@@ -332,6 +467,90 @@ Schematic.prototype.check_wires = function(c) {
}
}
}
}
Schematic
.
prototype
.
unselect_all
=
function
(
which
)
{
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
if
(
i
!=
which
)
this
.
components
[
i
].
set_select
(
false
);
}
Schematic
.
prototype
.
drag_begin
=
function
()
{
// let components know they're about to move
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
this
.
components
[
i
];
if
(
component
.
selected
)
component
.
move_begin
();
}
// remember where drag started
this
.
drag_x
=
this
.
cursor_x
;
this
.
drag_y
=
this
.
cursor_y
;
this
.
dragging
=
true
;
}
Schematic
.
prototype
.
drag_end
=
function
()
{
// let components know they're done moving
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
this
.
components
[
i
];
if
(
component
.
selected
)
component
.
move_end
();
}
this
.
dragging
=
false
;
}
Schematic
.
prototype
.
cut
=
function
()
{
// clear previous contents
this
.
clipboard
=
[];
// look for selected components, move them to clipboard.
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
c
=
this
.
components
[
i
];
if
(
c
.
selected
)
{
c
.
delete
();
this
.
clipboard
.
push
(
c
);
}
}
// update diagram view
this
.
redraw
();
}
Schematic
.
prototype
.
copy
=
function
()
{
// clear previous contents
this
.
clipboard
=
[];
// look for selected components, copy them to clipboard.
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
c
=
this
.
components
[
i
];
if
(
c
.
selected
)
this
.
clipboard
.
push
(
c
.
clone
(
this
,
c
.
x
,
c
.
y
));
}
}
Schematic
.
prototype
.
paste
=
function
()
{
// compute left,top of bounding box for origins of
// components in the clipboard
var
left
=
null
;
var
top
=
null
;
for
(
var
i
=
this
.
clipboard
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
c
=
this
.
clipboard
[
i
];
left
=
left
?
Math
.
min
(
left
,
c
.
x
)
:
left
;
top
=
top
?
Math
.
min
(
top
,
c
.
y
)
:
top
;
}
// clear current selections
this
.
unselect_all
(
-
1
);
this
.
redraw_background
();
// so we see any components that got unselected
// make clones of components on the clipboard, positioning
// them relative to the cursor
for
(
var
i
=
this
.
clipboard
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
c
=
this
.
clipboard
[
i
];
var
new_c
=
c
.
clone
(
this
,
this
.
cursor_x
+
(
c
.
x
-
left
),
this
.
cursor_y
+
(
c
.
y
-
top
));
this
.
add_component
(
new_c
);
new_c
.
set_select
(
true
);
}
// see what we've wrought
this
.
redraw
();
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
//
// Drawing support -- deals with scaling and scrolling of diagrama
// Drawing support -- deals with scaling and scrolling of diagrama
...
@@ -354,7 +573,7 @@ Schematic.prototype.redraw_background = function() {
...
@@ -354,7 +573,7 @@ Schematic.prototype.redraw_background = function() {
//c.strokeRect(0,0,this.width,this.height);
//c.strokeRect(0,0,this.width,this.height);
// grid
// grid
c
.
strokeStyle
=
"rgb(128,128,128)"
;
c
.
strokeStyle
=
grid_style
;
var
first_x
=
this
.
min_x
;
var
first_x
=
this
.
min_x
;
var
last_x
=
this
.
max_x
;
var
last_x
=
this
.
max_x
;
var
first_y
=
this
.
min_y
;
var
first_y
=
this
.
min_y
;
...
@@ -381,10 +600,17 @@ Schematic.prototype.redraw = function() {
...
@@ -381,10 +600,17 @@ Schematic.prototype.redraw = function() {
c
.
drawImage
(
this
.
bg_image
,
0
,
0
);
c
.
drawImage
(
this
.
bg_image
,
0
,
0
);
// selected components
// selected components
var
selections
=
false
;
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
this
.
components
[
i
];
var
component
=
this
.
components
[
i
];
if
(
component
.
selected
)
component
.
draw
(
c
);
if
(
component
.
selected
)
{
component
.
draw
(
c
);
selections
=
true
;
}
}
}
this
.
enable_tool
(
'cut'
,
selections
);
this
.
enable_tool
(
'copy'
,
selections
);
this
.
enable_tool
(
'paste'
,
this
.
clipboard
);
// connection points: draw one at each location
// connection points: draw one at each location
for
(
var
location
in
this
.
connection_points
)
{
for
(
var
location
in
this
.
connection_points
)
{
...
@@ -475,7 +701,7 @@ HTMLCanvasElement.prototype.relMouseCoords = function(event){
...
@@ -475,7 +701,7 @@ HTMLCanvasElement.prototype.relMouseCoords = function(event){
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// process special keys here since they don't get delivered correctly on keypress
// process special keys here since they don't get delivered correctly on keypress
Schematic
.
prototype
.
key_down
=
functio
n
(
event
)
{
function
schematic_key_dow
n
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
code
=
event
.
keyCode
;
var
code
=
event
.
keyCode
;
...
@@ -494,13 +720,14 @@ Schematic.prototype.key_down = function(event) {
...
@@ -494,13 +720,14 @@ Schematic.prototype.key_down = function(event) {
}
}
// process normal characters
// process normal characters
Schematic
.
prototype
.
key_press
=
function
(
event
)
{
function
schematic_key_press
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
code
=
window
.
event
?
event
.
keyCode
:
event
.
charCode
;
var
code
=
window
.
event
?
event
.
keyCode
:
event
.
charCode
;
var
char
=
String
.
fromCharCode
(
code
);
var
char
=
String
.
fromCharCode
(
code
);
if
(
char
==
'r'
||
char
==
'R'
)
{
// rotate
if
(
!
event
.
control
&&
!
event
.
altKey
&&
(
char
==
'r'
||
char
==
'R'
))
{
// rotate
// rotate
for
(
var
i
=
sch
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
for
(
var
i
=
sch
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
sch
.
components
[
i
];
var
component
=
sch
.
components
[
i
];
...
@@ -510,10 +737,33 @@ Schematic.prototype.key_press = function(event) {
...
@@ -510,10 +737,33 @@ Schematic.prototype.key_press = function(event) {
event
.
preventDefault
();
event
.
preventDefault
();
return
false
;
return
false
;
}
}
// cut
if
((
event
.
ctrlKey
||
event
.
altKey
)
&&
char
==
'x'
)
{
sch
.
cut
();
event
.
preventDefault
();
return
false
;
}
// copy
if
((
event
.
ctrlKey
||
event
.
altKey
)
&&
char
==
'c'
)
{
sch
.
copy
();
event
.
preventDefault
();
return
false
;
}
// paste
if
((
event
.
ctrlKey
||
event
.
altKey
)
&&
char
==
'v'
)
{
sch
.
paste
();
event
.
preventDefault
();
return
false
;
}
return
true
;
return
true
;
}
}
Schematic
.
prototype
.
mouse_enter
=
function
(
event
)
{
function
schematic_mouse_enter
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
...
@@ -540,21 +790,18 @@ Schematic.prototype.mouse_enter = function(event) {
...
@@ -540,21 +790,18 @@ Schematic.prototype.mouse_enter = function(event) {
sch
.
drawCursor
=
true
;
sch
.
drawCursor
=
true
;
sch
.
redraw
();
sch
.
redraw
();
sch
.
canvas
.
focus
();
// capture key strokes
sch
.
canvas
.
focus
();
// capture key strokes
return
false
;
}
}
Schematic
.
prototype
.
mouse_leave
=
function
(
event
)
{
function
schematic_mouse_leave
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
sch
.
drawCursor
=
false
;
sch
.
drawCursor
=
false
;
sch
.
redraw
();
sch
.
redraw
();
return
false
;
}
}
Schematic
.
prototype
.
unselect_all
=
function
(
which
)
{
function
schematic_mouse_down
(
event
)
{
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
if
(
i
!=
which
)
this
.
components
[
i
].
set_select
(
false
);
}
Schematic
.
prototype
.
mouse_down
=
function
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
else
event
.
preventDefault
();
else
event
.
preventDefault
();
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
...
@@ -566,6 +813,14 @@ Schematic.prototype.mouse_down = function(event) {
...
@@ -566,6 +813,14 @@ Schematic.prototype.mouse_down = function(event) {
sch
.
cursor_x
=
Math
.
round
(
x
/
sch
.
grid
)
*
sch
.
grid
;
sch
.
cursor_x
=
Math
.
round
(
x
/
sch
.
grid
)
*
sch
.
grid
;
sch
.
cursor_y
=
Math
.
round
(
y
/
sch
.
grid
)
*
sch
.
grid
;
sch
.
cursor_y
=
Math
.
round
(
y
/
sch
.
grid
)
*
sch
.
grid
;
/*
// for debugging... triggered by clicks in upper left corner
if (sch.cursor_x < 10 && sch.cursor_y < 10) {
sch.label_connection_points();
sch.append_message(JSON.stringify(sch.json()));
}
*/
// is mouse over a connection point? If so, start dragging a wire
// is mouse over a connection point? If so, start dragging a wire
var
cplist
=
sch
.
connection_points
[
sch
.
cursor_x
+
','
+
sch
.
cursor_y
];
var
cplist
=
sch
.
connection_points
[
sch
.
cursor_x
+
','
+
sch
.
cursor_y
];
if
(
cplist
&&
!
event
.
shiftKey
)
{
if
(
cplist
&&
!
event
.
shiftKey
)
{
...
@@ -598,9 +853,52 @@ Schematic.prototype.mouse_down = function(event) {
...
@@ -598,9 +853,52 @@ Schematic.prototype.mouse_down = function(event) {
}
}
sch
.
redraw_background
();
sch
.
redraw_background
();
return
false
;
}
function
schematic_mouse_move
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
sch
.
canvas
.
relMouseCoords
(
event
);
var
x
=
sch
.
canvas
.
mouse_x
/
sch
.
scale
+
sch
.
origin_x
;
var
y
=
sch
.
canvas
.
mouse_y
/
sch
.
scale
+
sch
.
origin_y
;
sch
.
cursor_x
=
Math
.
round
(
x
/
sch
.
grid
)
*
sch
.
grid
;
sch
.
cursor_y
=
Math
.
round
(
y
/
sch
.
grid
)
*
sch
.
grid
;
if
(
sch
.
wire
)
{
// update new wire end point
sch
.
wire
[
2
]
=
sch
.
cursor_x
;
sch
.
wire
[
3
]
=
sch
.
cursor_y
;
}
else
if
(
sch
.
dragging
)
{
// see how far we moved
var
dx
=
sch
.
cursor_x
-
sch
.
drag_x
;
var
dy
=
sch
.
cursor_y
-
sch
.
drag_y
;
if
(
dx
!=
0
||
dy
!=
0
)
{
// update position for next time
sch
.
drag_x
=
sch
.
cursor_x
;
sch
.
drag_y
=
sch
.
cursor_y
;
// give all components a shot at processing the event
for
(
var
i
=
sch
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
sch
.
components
[
i
];
if
(
component
.
selected
)
component
.
move
(
dx
,
dy
);
}
}
}
else
if
(
sch
.
select_rect
)
{
// update moving corner of selection rectangle
sch
.
select_rect
[
2
]
=
sch
.
canvas
.
mouse_x
;
sch
.
select_rect
[
3
]
=
sch
.
canvas
.
mouse_y
;
//sch.message(sch.select_rect.toString());
}
// just redraw dynamic components
sch
.
redraw
();
return
false
;
}
}
Schematic
.
prototype
.
mouse_up
=
function
(
event
)
{
function
schematic_mouse_up
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
else
event
.
preventDefault
();
else
event
.
preventDefault
();
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
...
@@ -642,9 +940,10 @@ Schematic.prototype.mouse_up = function(event) {
...
@@ -642,9 +940,10 @@ Schematic.prototype.mouse_up = function(event) {
sch
.
select_rect
=
null
;
sch
.
select_rect
=
null
;
sch
.
redraw_background
();
sch
.
redraw_background
();
}
}
return
false
;
}
}
Schematic
.
prototype
.
double_click
=
function
(
event
)
{
function
schematic_double_click
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
else
event
.
preventDefault
();
else
event
.
preventDefault
();
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
...
@@ -659,68 +958,8 @@ Schematic.prototype.double_click = function(event) {
...
@@ -659,68 +958,8 @@ Schematic.prototype.double_click = function(event) {
// see if we double-clicked a component. If so, edit it's properties
// see if we double-clicked a component. If so, edit it's properties
for
(
var
i
=
sch
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
for
(
var
i
=
sch
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
if
(
sch
.
components
[
i
].
edit_properties
(
x
,
y
))
break
;
if
(
sch
.
components
[
i
].
edit_properties
(
x
,
y
))
break
;
}
Schematic
.
prototype
.
drag_begin
=
function
()
{
// let components know they're about to move
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
this
.
components
[
i
];
if
(
component
.
selected
)
component
.
move_begin
();
}
// remember where drag started
return
false
;
this
.
drag_x
=
this
.
cursor_x
;
this
.
drag_y
=
this
.
cursor_y
;
this
.
dragging
=
true
;
}
Schematic
.
prototype
.
drag_end
=
function
()
{
// let components know they're done moving
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
this
.
components
[
i
];
if
(
component
.
selected
)
component
.
move_end
();
}
this
.
dragging
=
false
;
}
Schematic
.
prototype
.
mouse_move
=
function
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
sch
=
(
window
.
event
)
?
event
.
srcElement
.
schematic
:
event
.
target
.
schematic
;
sch
.
canvas
.
relMouseCoords
(
event
);
var
x
=
sch
.
canvas
.
mouse_x
/
sch
.
scale
+
sch
.
origin_x
;
var
y
=
sch
.
canvas
.
mouse_y
/
sch
.
scale
+
sch
.
origin_y
;
sch
.
cursor_x
=
Math
.
round
(
x
/
sch
.
grid
)
*
sch
.
grid
;
sch
.
cursor_y
=
Math
.
round
(
y
/
sch
.
grid
)
*
sch
.
grid
;
if
(
sch
.
wire
)
{
// update new wire end point
sch
.
wire
[
2
]
=
sch
.
cursor_x
;
sch
.
wire
[
3
]
=
sch
.
cursor_y
;
}
else
if
(
sch
.
dragging
)
{
// see how far we moved
var
dx
=
sch
.
cursor_x
-
sch
.
drag_x
;
var
dy
=
sch
.
cursor_y
-
sch
.
drag_y
;
if
(
dx
!=
0
||
dy
!=
0
)
{
// update position for next time
sch
.
drag_x
=
sch
.
cursor_x
;
sch
.
drag_y
=
sch
.
cursor_y
;
// give all components a shot at processing the event
for
(
var
i
=
sch
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
component
=
sch
.
components
[
i
];
if
(
component
.
selected
)
component
.
move
(
dx
,
dy
);
}
}
}
else
if
(
sch
.
select_rect
)
{
// update moving corner of selection rectangle
sch
.
select_rect
[
2
]
=
sch
.
canvas
.
mouse_x
;
sch
.
select_rect
[
3
]
=
sch
.
canvas
.
mouse_y
;
//sch.message(sch.select_rect.toString());
}
// just redraw dynamic components
sch
.
redraw
();
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
...
@@ -731,12 +970,10 @@ Schematic.prototype.mouse_move = function(event) {
...
@@ -731,12 +970,10 @@ Schematic.prototype.mouse_move = function(event) {
Schematic
.
prototype
.
message
=
function
(
message
)
{
Schematic
.
prototype
.
message
=
function
(
message
)
{
this
.
status
.
nodeValue
=
message
;
this
.
status
.
nodeValue
=
message
;
this
.
recompute_height
();
}
}
Schematic
.
prototype
.
append_message
=
function
(
message
)
{
Schematic
.
prototype
.
append_message
=
function
(
message
)
{
this
.
status
.
nodeValue
+=
' / '
+
message
;
this
.
status
.
nodeValue
+=
' / '
+
message
;
this
.
recompute_height
();
}
}
// set up a dialog with specified title, content and two buttons at
// set up a dialog with specified title, content and two buttons at
...
@@ -825,6 +1062,85 @@ function dialog_okay(event) {
...
@@ -825,6 +1062,85 @@ function dialog_okay(event) {
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
//
// Toolbar
//
////////////////////////////////////////////////////////////////////////////////
Schematic
.
prototype
.
add_tool
=
function
(
icon
,
tip
,
callback
)
{
var
img
=
document
.
createElement
(
'img'
);
img
.
src
=
icon
;
img
.
style
.
borderWidth
=
'1px'
;
img
.
style
.
borderStyle
=
'solid'
;
img
.
style
.
borderColor
=
background_style
;
img
.
style
.
position
=
'absolute'
;
img
.
style
.
padding
=
'2px'
;
img
.
addEventListener
(
'mouseover'
,
tool_enter
,
false
);
img
.
addEventListener
(
'mouseout'
,
tool_leave
,
false
);
img
.
addEventListener
(
'click'
,
tool_click
,
false
);
img
.
sch
=
this
;
img
.
tip
=
tip
;
img
.
callback
=
callback
;
this
.
toolbar
.
push
(
img
);
img
.
enabled
=
false
;
img
.
style
.
opacity
=
0.2
;
return
img
;
}
Schematic
.
prototype
.
enable_tool
=
function
(
tname
,
which
)
{
var
img
=
this
.
tools
[
tname
];
img
.
style
.
opacity
=
which
?
1.0
:
0.2
;
img
.
enabled
=
which
;
// if disabling tool, remove border and tip
if
(
!
which
)
{
img
.
style
.
borderColor
=
background_style
;
img
.
sch
.
message
(
''
);
}
}
// highlight tool button by turning on border, changing background
function
tool_enter
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
img
=
(
window
.
event
)
?
event
.
srcElement
:
event
.
target
;
if
(
img
.
enabled
)
{
img
.
style
.
borderColor
=
normal_style
;
img
.
sch
.
message
(
img
.
tip
);
img
.
opacity
=
1.0
;
}
}
// unhighlight tool button by turning off border, reverting to normal background
function
tool_leave
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
img
=
(
window
.
event
)
?
event
.
srcElement
:
event
.
target
;
if
(
img
.
enabled
)
{
img
.
style
.
borderColor
=
background_style
;
img
.
sch
.
message
(
''
);
}
}
// handle click on a tool
function
tool_click
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
img
=
(
window
.
event
)
?
event
.
srcElement
:
event
.
target
;
if
(
img
.
enabled
)
img
.
callback
.
call
(
img
.
sch
);
}
cut_icon
=
'data:image/gif;base64,R0lGODlhEAAQALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAAcALAAAAAAQABAAAAQu8MhJqz1g5qs7lxv2gRkQfuWomarXEgDRHjJhf3YtyRav0xcfcFgR0nhB5OwTAQA7'
;
copy_icon
=
'data:image/gif;base64,R0lGODlhEAAQALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAAcALAAAAAAQABAAAAQ+8MhJ6wE4Wwqef9gmdV8HiKZJrCz3ecS7TikWfzExvk+M9a0a4MbTkXCgTMeoHPJgG5+yF31SLazsTMTtViIAOw=='
;
paste_icon
=
'data:image/gif;base64,R0lGODlhEAAQALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAAcALAAAAAAQABAAAARL8MhJqwUYWJnxWp3GDcgAgCdQIqLKXmVLhhnyHiqpr7rME8AgocVDEB5IJHD0SyofBFzxGIQGAbvB0ZkcTq1CKK6z5YorwnR0w44AADs='
;
///////////////////////////////////////////////////////////////////////////////
//
// Parts bin
// Parts bin
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
...
@@ -839,13 +1155,17 @@ function Part(sch) {
...
@@ -839,13 +1155,17 @@ function Part(sch) {
this
.
canvas
=
document
.
createElement
(
'canvas'
);
this
.
canvas
=
document
.
createElement
(
'canvas'
);
this
.
canvas
.
style
.
borderStyle
=
'solid'
;
this
.
canvas
.
style
.
borderStyle
=
'solid'
;
this
.
canvas
.
style
.
borderWidth
=
'1px'
;
this
.
canvas
.
style
.
borderWidth
=
'1px'
;
this
.
canvas
.
style
.
borderColor
=
background_style
;
this
.
canvas
.
style
.
position
=
'absolute'
;
this
.
canvas
.
style
.
position
=
'absolute'
;
this
.
canvas
.
style
.
cursor
=
'default'
;
this
.
canvas
.
height
=
part_w
;
this
.
canvas
.
height
=
part_w
;
this
.
canvas
.
width
=
part_h
;
this
.
canvas
.
width
=
part_h
;
this
.
canvas
.
part
=
this
;
this
.
canvas
.
part
=
this
;
this
.
canvas
.
addEventListener
(
'mousedown'
,
this
.
mouse_down
,
false
);
this
.
canvas
.
addEventListener
(
'mouseover'
,
part_enter
,
false
);
this
.
canvas
.
addEventListener
(
'mouseup'
,
this
.
mouse_up
,
false
);
this
.
canvas
.
addEventListener
(
'mouseout'
,
part_leave
,
false
);
this
.
canvas
.
addEventListener
(
'mousedown'
,
part_mouse_down
,
false
);
this
.
canvas
.
addEventListener
(
'mouseup'
,
part_mouse_up
,
false
);
// make the part "clickable" by registering a dummy click handler
// make the part "clickable" by registering a dummy click handler
// this should make things work on the iPad
// this should make things work on the iPad
...
@@ -865,16 +1185,17 @@ Part.prototype.bottom = function() {
...
@@ -865,16 +1185,17 @@ Part.prototype.bottom = function() {
return
this
.
canvas
.
offsetTop
+
this
.
canvas
.
offsetHeight
;
return
this
.
canvas
.
offsetTop
+
this
.
canvas
.
offsetHeight
;
}
}
Part
.
prototype
.
set_component
=
function
(
component
)
{
Part
.
prototype
.
set_component
=
function
(
component
,
tip
)
{
this
.
component
=
component
;
this
.
component
=
component
;
this
.
tip
=
tip
;
// figure out scaling and centering of parts icon
// figure out scaling and centering of parts icon
var
b
=
component
.
bounding_box
;
var
b
=
component
.
bounding_box
;
var
dx
=
b
[
2
]
-
b
[
0
];
var
dx
=
b
[
2
]
-
b
[
0
];
var
dy
=
b
[
3
]
-
b
[
1
];
var
dy
=
b
[
3
]
-
b
[
1
];
this
.
scale
=
1
;
//Math.min(part_w/(1.2*dx),part_h/(1.2*dy));
this
.
scale
=
0.8
;
//Math.min(part_w/(1.2*dx),part_h/(1.2*dy));
this
.
origin_x
=
this
.
scale
*
(
b
[
0
]
+
dx
/
2.0
)
-
part_w
/
2.0
;
this
.
origin_x
=
b
[
0
]
+
dx
/
2.0
-
part_w
/
(
2.0
*
this
.
scale
)
;
this
.
origin_y
=
this
.
scale
*
(
b
[
1
]
+
dy
/
2.0
)
-
part_h
/
2.0
;
this
.
origin_y
=
b
[
1
]
+
dy
/
2.0
-
part_h
/
(
2.0
*
this
.
scale
)
;
this
.
redraw
();
this
.
redraw
();
}
}
...
@@ -883,7 +1204,7 @@ Part.prototype.redraw = function(part) {
...
@@ -883,7 +1204,7 @@ Part.prototype.redraw = function(part) {
var
c
=
this
.
canvas
.
getContext
(
'2d'
);
var
c
=
this
.
canvas
.
getContext
(
'2d'
);
// paint background color
// paint background color
c
.
fillStyle
=
this
.
selected
?
selected_style
:
element
_style
;
c
.
fillStyle
=
this
.
selected
?
selected_style
:
background
_style
;
c
.
fillRect
(
0
,
0
,
part_w
,
part_h
);
c
.
fillRect
(
0
,
0
,
part_w
,
part_h
);
if
(
this
.
component
)
this
.
component
.
draw
(
c
);
if
(
this
.
component
)
this
.
component
.
draw
(
c
);
...
@@ -919,20 +1240,42 @@ Part.prototype.draw_text = function(c,text,x,y,size) {
...
@@ -919,20 +1240,42 @@ Part.prototype.draw_text = function(c,text,x,y,size) {
// no text displayed for the parts icon
// no text displayed for the parts icon
}
}
Part
.
prototype
.
mouse_down
=
function
(
event
)
{
function
part_enter
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
canvas
=
(
window
.
event
)
?
event
.
srcElement
:
event
.
target
;
var
part
=
canvas
.
part
;
canvas
.
style
.
borderColor
=
normal_style
;
part
.
sch
.
message
(
part
.
tip
+
': drag onto diagram to insert'
);
return
false
;
}
function
part_leave
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
canvas
=
(
window
.
event
)
?
event
.
srcElement
:
event
.
target
;
var
part
=
canvas
.
part
;
canvas
.
style
.
borderColor
=
background_style
;
part
.
sch
.
message
(
''
);
return
false
;
}
function
part_mouse_down
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
var
part
=
(
window
.
event
)
?
event
.
srcElement
.
part
:
event
.
target
.
part
;
var
part
=
(
window
.
event
)
?
event
.
srcElement
.
part
:
event
.
target
.
part
;
part
.
select
(
true
);
part
.
select
(
true
);
part
.
sch
.
new_part
=
part
;
part
.
sch
.
new_part
=
part
;
return
false
;
}
}
Part
.
prototype
.
mouse_up
=
function
(
event
)
{
function
part_mouse_up
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
if
(
!
event
)
event
=
window
.
event
;
var
part
=
(
window
.
event
)
?
event
.
srcElement
.
part
:
event
.
target
.
part
;
var
part
=
(
window
.
event
)
?
event
.
srcElement
.
part
:
event
.
target
.
part
;
part
.
select
(
false
);
part
.
select
(
false
);
part
.
sch
.
new_part
=
null
;
part
.
sch
.
new_part
=
null
;
return
false
;
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
...
@@ -987,8 +1330,6 @@ function intersect(r1,r2) {
...
@@ -987,8 +1330,6 @@ function intersect(r1,r2) {
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
property_size
=
5
;
// point size for Component property text
property_size
=
5
;
// point size for Component property text
normal_style
=
'rgb(0,0,0)'
;
// color for unselected components
selected_style
=
'rgb(64,255,64)'
;
// highlight color for selected components
function
Component
(
sch
,
x
,
y
,
rotation
)
{
function
Component
(
sch
,
x
,
y
,
rotation
)
{
this
.
sch
=
sch
;
this
.
sch
=
sch
;
...
@@ -1002,6 +1343,18 @@ function Component(sch,x,y,rotation) {
...
@@ -1002,6 +1343,18 @@ function Component(sch,x,y,rotation) {
this
.
connections
=
[];
this
.
connections
=
[];
}
}
Component
.
prototype
.
json
=
function
()
{
var
props
=
{};
for
(
var
p
in
this
.
properties
)
props
[
p
]
=
this
.
properties
[
p
];
var
conns
=
[];
for
(
var
i
=
0
;
i
<
this
.
connections
.
length
;
i
++
)
conns
.
push
(
this
.
connections
[
i
].
json
());
var
json
=
[
this
.
type
,[
this
.
x
,
this
.
y
,
this
.
rotation
],
props
,
conns
];
return
json
;
}
Component
.
prototype
.
add_connection
=
function
(
offset_x
,
offset_y
)
{
Component
.
prototype
.
add_connection
=
function
(
offset_x
,
offset_y
)
{
this
.
connections
.
push
(
new
ConnectionPoint
(
this
,
offset_x
,
offset_y
));
this
.
connections
.
push
(
new
ConnectionPoint
(
this
,
offset_x
,
offset_y
));
}
}
...
@@ -1227,6 +1580,31 @@ Component.prototype.edit_properties = function(x,y) {
...
@@ -1227,6 +1580,31 @@ Component.prototype.edit_properties = function(x,y) {
}
else
return
false
;
}
else
return
false
;
}
}
// clear the labels on all connections
Component
.
prototype
.
clear_labels
=
function
()
{
for
(
var
i
=
this
.
connections
.
length
-
1
;
i
>=
0
;
--
i
)
{
this
.
connections
[
i
].
clear_label
();
}
}
// default action: don't propagate label
Component
.
prototype
.
propagate_label
=
function
(
label
)
{
}
// give components a chance to generate default labels for their connection(s)
// default action: do nothing
Component
.
prototype
.
add_default_labels
=
function
()
{
}
// component should generate labels for all unlabeled connections
Component
.
prototype
.
label_connections
=
function
()
{
for
(
var
i
=
this
.
connections
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
cp
=
this
.
connections
[
i
];
if
(
!
cp
.
label
)
cp
.
propagate_label
(
this
.
sch
.
get_next_label
());
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Connection point
// Connection point
...
@@ -1241,12 +1619,36 @@ function ConnectionPoint(parent,x,y) {
...
@@ -1241,12 +1619,36 @@ function ConnectionPoint(parent,x,y) {
this
.
offset_y
=
y
;
this
.
offset_y
=
y
;
this
.
location
=
''
;
this
.
location
=
''
;
this
.
update_location
();
this
.
update_location
();
this
.
label
=
null
;
}
}
ConnectionPoint
.
prototype
.
toString
=
function
()
{
ConnectionPoint
.
prototype
.
toString
=
function
()
{
return
'<ConnectionPoint ('
+
this
.
offset_x
+
','
+
this
.
offset_y
+
') '
+
this
.
parent
.
toString
()
+
'>'
;
return
'<ConnectionPoint ('
+
this
.
offset_x
+
','
+
this
.
offset_y
+
') '
+
this
.
parent
.
toString
()
+
'>'
;
}
}
ConnectionPoint
.
prototype
.
json
=
function
()
{
return
this
.
label
;
}
ConnectionPoint
.
prototype
.
clear_label
=
function
()
{
this
.
label
=
null
;
}
ConnectionPoint
.
prototype
.
propagate_label
=
function
(
label
)
{
// should we check if existing label is the same? it should be...
if
(
this
.
label
==
null
)
{
// label this connection point
this
.
label
=
label
;
// propagate label to coincident connection points
this
.
parent
.
sch
.
propagate_label
(
label
,
this
.
location
);
// possibly label other cp's for this device?
this
.
parent
.
propagate_label
(
label
);
}
}
ConnectionPoint
.
prototype
.
update_location
=
function
()
{
ConnectionPoint
.
prototype
.
update_location
=
function
()
{
// update location string which we use as a key to find coincident connection points
// update location string which we use as a key to find coincident connection points
var
old_location
=
this
.
location
;
var
old_location
=
this
.
location
;
...
@@ -1306,6 +1708,11 @@ Wire.prototype.toString = function() {
...
@@ -1306,6 +1708,11 @@ Wire.prototype.toString = function() {
return
'<Wire ('
+
this
.
x
+
','
+
this
.
y
+
') ('
+
(
this
.
x
+
this
.
dx
)
+
','
+
(
this
.
y
+
this
.
dy
)
+
')>'
;
return
'<Wire ('
+
this
.
x
+
','
+
this
.
y
+
') ('
+
(
this
.
x
+
this
.
dx
)
+
','
+
(
this
.
y
+
this
.
dy
)
+
')>'
;
}
}
Wire
.
prototype
.
json
=
function
()
{
var
json
=
[
'w'
,[
this
.
x
,
this
.
y
,
this
.
x
+
this
.
dx
,
this
.
y
+
this
.
dy
]];
return
json
;
}
Wire
.
prototype
.
draw
=
function
(
c
)
{
Wire
.
prototype
.
draw
=
function
(
c
)
{
this
.
draw_line
(
c
,
0
,
0
,
this
.
dx
,
this
.
dy
);
this
.
draw_line
(
c
,
0
,
0
,
this
.
dx
,
this
.
dy
);
}
}
...
@@ -1367,6 +1774,18 @@ Wire.prototype.move_end = function() {
...
@@ -1367,6 +1774,18 @@ Wire.prototype.move_end = function() {
this
.
sch
.
check_wires
(
this
);
this
.
sch
.
check_wires
(
this
);
}
}
// wires "conduct" their label to the other end
Wire
.
prototype
.
propagate_label
=
function
(
label
)
{
// don't worry about relabeling a cp, it won't recurse!
this
.
connections
[
0
].
propagate_label
(
label
);
this
.
connections
[
1
].
propagate_label
(
label
);
}
// some actual component will start the labeling of electrical nodes,
// so do nothing here
Wire
.
prototype
.
label_connections
=
function
()
{
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Ground
// Ground
...
@@ -1378,6 +1797,7 @@ function Ground(sch,x,y,rotation) {
...
@@ -1378,6 +1797,7 @@ function Ground(sch,x,y,rotation) {
this
.
add_connection
(
0
,
0
);
this
.
add_connection
(
0
,
0
);
this
.
bounding_box
=
[
-
6
,
0
,
6
,
8
];
this
.
bounding_box
=
[
-
6
,
0
,
6
,
8
];
this
.
update_coords
();
this
.
update_coords
();
this
.
type
=
'g'
;
}
}
Ground
.
prototype
=
new
Component
();
Ground
.
prototype
=
new
Component
();
Ground
.
prototype
.
constructor
=
Ground
;
Ground
.
prototype
.
constructor
=
Ground
;
...
@@ -1395,6 +1815,12 @@ Ground.prototype.clone = function(sch,x,y) {
...
@@ -1395,6 +1815,12 @@ Ground.prototype.clone = function(sch,x,y) {
return
new
Ground
(
sch
,
x
,
y
,
this
.
rotation
);
return
new
Ground
(
sch
,
x
,
y
,
this
.
rotation
);
}
}
// give components a chance to generate a label for their connection(s)
// default action: do nothing
Ground
.
prototype
.
add_default_labels
=
function
()
{
this
.
connections
[
0
].
propagate_label
(
'0'
);
// canonical label for GND node
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Resistor
// Resistor
...
@@ -1409,6 +1835,7 @@ function Resistor(sch,x,y,rotation,name,r) {
...
@@ -1409,6 +1835,7 @@ function Resistor(sch,x,y,rotation,name,r) {
this
.
add_connection
(
0
,
48
);
this
.
add_connection
(
0
,
48
);
this
.
bounding_box
=
[
-
4
,
0
,
4
,
48
];
this
.
bounding_box
=
[
-
4
,
0
,
4
,
48
];
this
.
update_coords
();
this
.
update_coords
();
this
.
type
=
'r'
;
}
}
Resistor
.
prototype
=
new
Component
();
Resistor
.
prototype
=
new
Component
();
Resistor
.
prototype
.
constructor
=
Resistor
;
Resistor
.
prototype
.
constructor
=
Resistor
;
...
@@ -1451,6 +1878,7 @@ function Capacitor(sch,x,y,rotation,name,c) {
...
@@ -1451,6 +1878,7 @@ function Capacitor(sch,x,y,rotation,name,c) {
this
.
add_connection
(
0
,
48
);
this
.
add_connection
(
0
,
48
);
this
.
bounding_box
=
[
-
8
,
0
,
8
,
48
];
this
.
bounding_box
=
[
-
8
,
0
,
8
,
48
];
this
.
update_coords
();
this
.
update_coords
();
this
.
type
=
'c'
;
}
}
Capacitor
.
prototype
=
new
Component
();
Capacitor
.
prototype
=
new
Component
();
Capacitor
.
prototype
.
constructor
=
Capacitor
;
Capacitor
.
prototype
.
constructor
=
Capacitor
;
...
@@ -1488,6 +1916,7 @@ function Inductor(sch,x,y,rotation,name,l) {
...
@@ -1488,6 +1916,7 @@ function Inductor(sch,x,y,rotation,name,l) {
this
.
add_connection
(
0
,
48
);
this
.
add_connection
(
0
,
48
);
this
.
bounding_box
=
[
-
4
,
0
,
5
,
48
];
this
.
bounding_box
=
[
-
4
,
0
,
5
,
48
];
this
.
update_coords
();
this
.
update_coords
();
this
.
type
=
'l'
;
}
}
Inductor
.
prototype
=
new
Component
();
Inductor
.
prototype
=
new
Component
();
Inductor
.
prototype
.
constructor
=
Inductor
;
Inductor
.
prototype
.
constructor
=
Inductor
;
...
@@ -1568,7 +1997,7 @@ Source.prototype.clone = function(sch,x,y) {
...
@@ -1568,7 +1997,7 @@ Source.prototype.clone = function(sch,x,y) {
function
VSource
(
sch
,
x
,
y
,
rotation
,
name
,
value
)
{
function
VSource
(
sch
,
x
,
y
,
rotation
,
name
,
value
)
{
Source
.
call
(
this
,
sch
,
x
,
y
,
rotation
,
name
,
'v'
,
value
);
Source
.
call
(
this
,
sch
,
x
,
y
,
rotation
,
name
,
'v'
,
value
);
this
.
type
=
'v'
;
}
}
VSource
.
prototype
=
new
Component
();
VSource
.
prototype
=
new
Component
();
VSource
.
prototype
.
constructor
=
VSource
;
VSource
.
prototype
.
constructor
=
VSource
;
...
@@ -1578,7 +2007,7 @@ VSource.prototype.clone = Source.prototype.clone;
...
@@ -1578,7 +2007,7 @@ VSource.prototype.clone = Source.prototype.clone;
function
ISource
(
sch
,
x
,
y
,
rotation
,
name
,
value
)
{
function
ISource
(
sch
,
x
,
y
,
rotation
,
name
,
value
)
{
Source
.
call
(
this
,
sch
,
x
,
y
,
rotation
,
name
,
'i'
,
value
);
Source
.
call
(
this
,
sch
,
x
,
y
,
rotation
,
name
,
'i'
,
value
);
this
.
type
=
'i'
;
}
}
ISource
.
prototype
=
new
Component
();
ISource
.
prototype
=
new
Component
();
ISource
.
prototype
.
constructor
=
ISource
;
ISource
.
prototype
.
constructor
=
ISource
;
...
...
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