Sticky machine and machine command controls are implemented in Jekyll now, too

This commit is contained in:
Jeff Parsons 2017-01-03 16:31:08 -08:00 committed by Jeff Parsons
commit 35eb925f62
5 changed files with 51 additions and 83 deletions

View file

@ -0,0 +1,16 @@
{% comment %}
As discussed in /_posts/2017-01-03-pdp-11-tutorials.md, when a page (usually part of a tutorial)
wants to create a control that tests some feature of a machine, the page will define a machine command
using a Liquid-style include that looks like:
{% include machine-command.html type='button' label='Try It!' machine='vt100' component='Keyboard' command='sendString' value='Hello World' %}
and which should generate something like:
<button type="button" onclick="commandMachine('vt100','Keyboard','sendString','Hello World')">Try It!</button>
Well, that's us. So let's do it!
{% endcomment %}
{% if include.type == "button" %}<button type="button" onclick="commandMachine('{{ include.machine }}','{{ include.component }}','{{ include.command }}','{{ include.value }}')">{{ include.label }}</button>{% else %}<!-- Unrecognized machine control type: {{ include.type }} -->{% endif %}

View file

@ -145,46 +145,8 @@ of our Markdown or XML documents. Examples: 'automount' becomes 'autoMount', 'a
{% endif %}
<script type="text/javascript">{{ machine_embed }}('{{ machine.id }}','{{ machine_config }}','{{ machine_template }}','{{ machine_parms }}');</script>
{% if machine.sticky == "top" %}
<script type="text/javascript">
var startMachinePos = -1;
window.onscroll = function() {
var machine = document.getElementById('{{ machine.id }}');
if (machine) {
var machineFooter = document.getElementById('{{ machine.id }}.footer');
if (startMachinePos < 0) {
startMachinePos = findTop(machine);
}
if (window.pageYOffset <= startMachinePos) {
machine.style.position = 'relative';
machine.style.zIndex = 'auto';
machine.style.backgroundColor = '';
machine.style.paddingRight = 0;
if (machineFooter) machineFooter.style.paddingTop = 0;
} else {
machine.style.position = 'fixed';
machine.style.zIndex = 1;
machine.style.backgroundColor = 'white';
machine.style.paddingRight = '30px';
machine.style.top = 0;
if (machineFooter) machineFooter.style.paddingTop = machine.offsetHeight + 'px';
}
}
};
function findTop(obj) {
var curTop = 0;
if (typeof obj.offsetParent != 'undefined' && obj.offsetParent) {
while (obj.offsetParent) {
curTop += obj.offsetTop;
obj = obj.offsetParent;
}
curTop += obj.offsetTop;
}
else if (obj.y) {
curTop += obj.y;
}
return curTop;
}
</script>
<script type="text/javascript" src="{{ site.baseurl }}/modules/shared/lib/sticky.js"></script>
<script type="text/javascript">addStickyMachine('{{ machine.id }}');</script>
{% endif %}
{% if page.build %}
<script type="text/javascript" src="{{ site.baseurl }}/modules/build/lib/build.js"></script>

View file

@ -16,7 +16,7 @@ machines:
sticky: top
---
Introducing PDP-11 tutorials. For more information, keep scrolling.
Introducing PDP-11 tutorials. For more details, keep scrolling, and keep your eye on the VT100 below.
{% include machine.html id="vt100" %}
@ -26,34 +26,42 @@ like [bitsavers.org](http://bitsavers.org), I suspect most people don't have a l
reading old manuals.
In an effort to remedy that situation, I'm adding some new features to PCjs. The first feature is what I call
"Sticky Machines", and it's more a website feature than a machine feature. At the top of any PCjs webpage, in the
*machines* section, a machine can now have a *sticky* property. For now, the only supported value is "top"; e.g.:
"Sticky Machines", and it's really just a new feature of the PCjs website. At the top of any PCjs webpage, in the
*machines* section, a machine can now define a *sticky* property. For now, the only supported value is "top"; e.g.:
machines:
- id: vt100
type: pc8080
config: /devices/pc8080/machine/vt100/machine.xml
connection: serialPort->test1170.dl11
sticky: top
type: pc8080
config: /devices/pc8080/machine/vt100/machine.xml
connection: serialPort->test1170.dl11
sticky: top
A sticky machine makes it easier to construct a tutorial page for a single machine, by preventing that machine from
scrolling off the top of the page; it "sticks" to the top instead. The rest of the page scrolls normally, allowing the
user to progress at their own pace through the text and/or images of an accompanying tutorial.
scrolling off the top; it "sticks" to the top instead. The rest of the page scrolls normally, allowing the user to
progress at their own pace through the text and/or images of an accompanying tutorial.
The second feature is a generalized method for sending commands to components within a machine. For example, if we
want to send some keyboard commands to machine:
want to send some keyboard commands to a machine:
{% raw %}
{% include machine-command.html type='button' label='Try It!' machine='vt100' component='Keyboard' command='sendString' value='Hello World' %}
{% endraw %}
which should translate into a control that looks like:
which should translate into a control that looks like this:
<button type="button" onclick="commandMachine('vt100','Keyboard','sendString','Hello World')">Try It!</button>
In fact, let's try it now. {% include machine-command.html type='button' label='Try It!' machine='vt100' component='Keyboard' command='sendString' value='Hello World' %}
Obviously, every component we want to control will need to be updated to export the necessary functions.
Obviously, every component we want to control will need to be updated to export the necessary "command" functions.
So expect some PDPjs tutorials in the near future, featuring sticky machines and built-in command demos. Some
commands will be very simple, like the keyboard injection command shown above. Others will perform more sophisticated
operations, such as loading and booting a particular disk, running a particular application, automatically flipping
selected Front Panel switches, and so on.
Finally, in case you're wondering why there's another machine below, well, what did you think the VT100 was talking to?
This PDP-11/70, of course.
{% include machine.html id="test1170" %}

View file

@ -8,8 +8,6 @@ dl, dd, ol, ul, figure {
padding: 0;
}
/**
* Basic styling
*/
@ -23,8 +21,6 @@ body {
-webkit-text-size-adjust: 100%;
}
/**
* Set `margin-bottom` to maintain vertical rhythm
*/
@ -35,8 +31,6 @@ ul, ol, dl, figure,
margin-bottom: $spacing-unit / 2;
}
/**
* Images
*/
@ -45,8 +39,6 @@ img {
vertical-align: middle;
}
/**
* Figures
*/
@ -58,8 +50,6 @@ figcaption {
font-size: $small-font-size;
}
/**
* Lists
*/
@ -74,8 +64,6 @@ li {
}
}
/**
* Headings
*/
@ -83,8 +71,6 @@ h1, h2, h3, h4, h5, h6 {
font-weight: 300;
}
/**
* Links
*/
@ -102,8 +88,6 @@ a {
}
}
/**
* Blockquotes
*/
@ -124,8 +108,6 @@ blockquote {
}
}
/**
* Code formatting
*/
@ -153,8 +135,6 @@ pre {
}
}
/**
* Wrapper
*/
@ -175,8 +155,6 @@ pre {
}
}
/**
* Clearfix
*/
@ -189,8 +167,6 @@ pre {
}
}
/**
* Icons
*/

View file

@ -86,8 +86,6 @@
}
}
/**
* Site footer
*/
@ -156,8 +154,6 @@
}
}
/**
* Page content
*/
@ -188,8 +184,6 @@
font-size: 24px;
}
/**
* Posts
*/
@ -241,7 +235,19 @@
.machine {
margin-bottom: 16px;
}
.machine-floating {
position: relative;
z-index: auto;
background-color: transparent;
padding-right: 0;
}
.machine-sticky {
position: fixed !important;
z-index: 1 !important;
background-color: #ffffff !important;
padding-right: 30px !important;
top: 0 !important;
}
.screenshot-frame {
display: inline-block;
margin: 8px;