Stop hg ignoring the build dir.

I want to include the HTML output of sphinx so you can view it without having to install sphinx.
This commit is contained in:
Simon Forman 2019-05-07 17:45:39 -07:00
parent 4f5caf4ab3
commit 21b69ea260
70 changed files with 20213 additions and 3 deletions

View File

@ -1,5 +1,4 @@
.*\.pyc$ .*\.pyc$
build
.hypothesis .hypothesis
.pytest_cache .pytest_cache
.vscode .vscode

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 045f1325f6d2a1aed4dff11fe7e98c72
tags: 645f666f9bcd5a90fca523b33c5a78b7

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,105 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Overview: module code &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/language_data.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>All modules for which code is available</h1>
<ul><li><a href="joy/vui/core.html">joy.vui.core</a></li>
<li><a href="joy/vui/display.html">joy.vui.display</a></li>
<li><a href="joy/vui/main.html">joy.vui.main</a></li>
<li><a href="joy/vui/persist_task.html">joy.vui.persist_task</a></li>
<li><a href="joy/vui/stack_viewer.html">joy.vui.stack_viewer</a></li>
<li><a href="joy/vui/text_viewer.html">joy.vui.text_viewer</a></li>
<li><a href="joy/vui/viewer.html">joy.vui.viewer</a></li>
</ul>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,380 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.vui.core &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.vui.core</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="c1">#</span>
<span class="c1"># Copyright © 2019 Simon Forman</span>
<span class="c1">#</span>
<span class="c1"># This file is part of Thun</span>
<span class="c1">#</span>
<span class="c1"># Thun is free software: you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># Thun is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with Thun. If not see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">Core</span>
<span class="sd">=====================</span>
<span class="sd">The core module defines a bunch of system-wide &quot;constants&quot; (some colors</span>
<span class="sd">and PyGame event groups), the message classes for Oberon-style message</span>
<span class="sd">passing, a &quot;world&quot; class that holds the main context for the system, and</span>
<span class="sd">a mainloop class that manages the, uh, main loop (the PyGame event queue.)</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">sys</span> <span class="k">import</span> <span class="n">stderr</span>
<span class="kn">from</span> <span class="nn">traceback</span> <span class="k">import</span> <span class="n">format_exc</span>
<span class="kn">import</span> <span class="nn">pygame</span>
<span class="kn">from</span> <span class="nn">joy.joy</span> <span class="k">import</span> <span class="n">run</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">stack_to_string</span>
<span class="n">COMMITTER</span> <span class="o">=</span> <span class="s1">&#39;Joy &lt;auto-commit@example.com&gt;&#39;</span>
<span class="n">BLACK</span> <span class="o">=</span> <span class="n">FOREGROUND</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span>
<span class="n">GREY</span> <span class="o">=</span> <span class="mi">127</span><span class="p">,</span> <span class="mi">127</span><span class="p">,</span> <span class="mi">127</span>
<span class="n">WHITE</span> <span class="o">=</span> <span class="n">BACKGROUND</span> <span class="o">=</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span>
<span class="n">BLUE</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">255</span>
<span class="n">GREEN</span> <span class="o">=</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">70</span>
<span class="n">MOUSE_EVENTS</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">MOUSEMOTION</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">MOUSEBUTTONDOWN</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">MOUSEBUTTONUP</span>
<span class="p">})</span>
<span class="s1">&#39;PyGame mouse events.&#39;</span>
<span class="n">ARROW_KEYS</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_UP</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_DOWN</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_LEFT</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_RIGHT</span>
<span class="p">})</span>
<span class="s1">&#39;PyGame arrow key events.&#39;</span>
<span class="n">TASK_EVENTS</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">pygame</span><span class="o">.</span><span class="n">USEREVENT</span><span class="p">,</span> <span class="n">pygame</span><span class="o">.</span><span class="n">NUMEVENTS</span><span class="p">))</span>
<span class="s1">&#39;Keep track of all possible task events.&#39;</span>
<span class="n">AVAILABLE_TASK_EVENTS</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">TASK_EVENTS</span><span class="p">)</span>
<span class="s1">&#39;Task IDs that have not been assigned to a task.&#39;</span>
<span class="n">ALLOWED_EVENTS</span> <span class="o">=</span> <span class="p">[</span><span class="n">pygame</span><span class="o">.</span><span class="n">QUIT</span><span class="p">,</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KEYUP</span><span class="p">,</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KEYDOWN</span><span class="p">]</span>
<span class="n">ALLOWED_EVENTS</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">MOUSE_EVENTS</span><span class="p">)</span>
<span class="n">ALLOWED_EVENTS</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">TASK_EVENTS</span><span class="p">)</span>
<span class="s1">&#39;Event &quot;mask&quot; for PyGame event queue, we are only interested in these event types.&#39;</span>
<span class="n">ERROR</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">PENDING</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">SUCCESS</span> <span class="o">=</span> <span class="mi">1</span>
<span class="c1"># &#39;Message status codes... dunno if this is a good idea or not...</span>
<div class="viewcode-block" id="Message"><a class="viewcode-back" href="../../../core.html#joy.vui.core.Message">[docs]</a><span class="k">class</span> <span class="nc">Message</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Message base class. Contains ``sender`` field.&#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sender</span> <span class="o">=</span> <span class="n">sender</span></div>
<div class="viewcode-block" id="CommandMessage"><a class="viewcode-back" href="../../../core.html#joy.vui.core.CommandMessage">[docs]</a><span class="k">class</span> <span class="nc">CommandMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;For commands, adds ``command`` field.&#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">command</span><span class="p">):</span>
<span class="n">Message</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">command</span></div>
<div class="viewcode-block" id="ModifyMessage"><a class="viewcode-back" href="../../../core.html#joy.vui.core.ModifyMessage">[docs]</a><span class="k">class</span> <span class="nc">ModifyMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> For when resources are modified, adds ``subject`` and ``details``</span>
<span class="sd"> fields.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">subject</span><span class="p">,</span> <span class="o">**</span><span class="n">details</span><span class="p">):</span>
<span class="n">Message</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">subject</span> <span class="o">=</span> <span class="n">subject</span>
<span class="bp">self</span><span class="o">.</span><span class="n">details</span> <span class="o">=</span> <span class="n">details</span></div>
<div class="viewcode-block" id="OpenMessage"><a class="viewcode-back" href="../../../core.html#joy.vui.core.OpenMessage">[docs]</a><span class="k">class</span> <span class="nc">OpenMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> For when resources are modified, adds ``name``, content_id``,</span>
<span class="sd"> ``status``, and ``traceback`` fields.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="n">Message</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="bp">self</span><span class="o">.</span><span class="n">content_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">thing</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">PENDING</span>
<span class="bp">self</span><span class="o">.</span><span class="n">traceback</span> <span class="o">=</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="PersistMessage"><a class="viewcode-back" href="../../../core.html#joy.vui.core.PersistMessage">[docs]</a><span class="k">class</span> <span class="nc">PersistMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> For when resources are modified, adds ``content_id`` and ``details``</span>
<span class="sd"> fields.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">content_id</span><span class="p">,</span> <span class="o">**</span><span class="n">details</span><span class="p">):</span>
<span class="n">Message</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">content_id</span> <span class="o">=</span> <span class="n">content_id</span>
<span class="bp">self</span><span class="o">.</span><span class="n">details</span> <span class="o">=</span> <span class="n">details</span></div>
<div class="viewcode-block" id="ShutdownMessage"><a class="viewcode-back" href="../../../core.html#joy.vui.core.ShutdownMessage">[docs]</a><span class="k">class</span> <span class="nc">ShutdownMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Signals that the system is shutting down.&#39;&#39;&#39;</span></div>
<span class="c1"># Joy Interpreter &amp; Context</span>
<div class="viewcode-block" id="World"><a class="viewcode-back" href="../../../core.html#joy.vui.core.World">[docs]</a><span class="k">class</span> <span class="nc">World</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> This object contains the system context, the stack, dictionary, a</span>
<span class="sd"> reference to the display broadcast method, and the log.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack_id</span><span class="p">,</span> <span class="n">stack_holder</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">notify</span><span class="p">,</span> <span class="n">log</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span> <span class="o">=</span> <span class="n">stack_holder</span>
<span class="bp">self</span><span class="o">.</span><span class="n">dictionary</span> <span class="o">=</span> <span class="n">dictionary</span>
<span class="bp">self</span><span class="o">.</span><span class="n">notify</span> <span class="o">=</span> <span class="n">notify</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack_id</span> <span class="o">=</span> <span class="n">stack_id</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log</span> <span class="o">=</span> <span class="n">log</span><span class="o">.</span><span class="n">lines</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log_id</span> <span class="o">=</span> <span class="n">log</span><span class="o">.</span><span class="n">content_id</span>
<div class="viewcode-block" id="World.handle"><a class="viewcode-back" href="../../../core.html#joy.vui.core.World.handle">[docs]</a> <span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Deal with updates to the stack and commands.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">ModifyMessage</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">subject</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span>
<span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_log_lines</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> &lt;-&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_stack</span><span class="p">())</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">CommandMessage</span><span class="p">):</span>
<span class="k">return</span>
<span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">dictionary</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_log_lines</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;-&gt; </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">c</span><span class="p">,))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">dictionary</span> <span class="o">=</span> <span class="n">run</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span>
<span class="n">mm</span> <span class="o">=</span> <span class="n">ModifyMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span><span class="p">,</span> <span class="n">content_id</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">stack_id</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">notify</span><span class="p">(</span><span class="n">mm</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">_log_lines</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">lines</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">notify</span><span class="p">(</span><span class="n">ModifyMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="p">,</span> <span class="n">content_id</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">log_id</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">format_stack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">except</span><span class="p">:</span>
<span class="nb">print</span> <span class="o">&gt;&gt;</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">format_exc</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span></div>
<div class="viewcode-block" id="push"><a class="viewcode-back" href="../../../core.html#joy.vui.core.push">[docs]</a><span class="k">def</span> <span class="nf">push</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">item</span><span class="p">,</span> <span class="n">notify</span><span class="p">,</span> <span class="n">stack_name</span><span class="o">=</span><span class="s1">&#39;stack.pickle&#39;</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Helper function to push an item onto the system stack with message.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">om</span> <span class="o">=</span> <span class="n">OpenMessage</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">stack_name</span><span class="p">)</span>
<span class="n">notify</span><span class="p">(</span><span class="n">om</span><span class="p">)</span>
<span class="k">if</span> <span class="n">om</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="n">SUCCESS</span><span class="p">:</span>
<span class="n">om</span><span class="o">.</span><span class="n">thing</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">om</span><span class="o">.</span><span class="n">thing</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">notify</span><span class="p">(</span><span class="n">ModifyMessage</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">om</span><span class="o">.</span><span class="n">thing</span><span class="p">,</span> <span class="n">content_id</span><span class="o">=</span><span class="n">om</span><span class="o">.</span><span class="n">content_id</span><span class="p">))</span>
<span class="k">return</span> <span class="n">om</span><span class="o">.</span><span class="n">status</span></div>
<div class="viewcode-block" id="open_viewer_on_string"><a class="viewcode-back" href="../../../core.html#joy.vui.core.open_viewer_on_string">[docs]</a><span class="k">def</span> <span class="nf">open_viewer_on_string</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">notify</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Helper function to open a text viewer on a string.</span>
<span class="sd"> Typically used to show tracebacks.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">push</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">notify</span><span class="p">)</span>
<span class="n">notify</span><span class="p">(</span><span class="n">CommandMessage</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="s1">&#39;good_viewer_location open_viewer&#39;</span><span class="p">))</span></div>
<span class="c1"># main loop</span>
<div class="viewcode-block" id="TheLoop"><a class="viewcode-back" href="../../../core.html#joy.vui.core.TheLoop">[docs]</a><span class="k">class</span> <span class="nc">TheLoop</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> The main loop manages tasks and the PyGame event queue</span>
<span class="sd"> and framerate clock.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">FRAME_RATE</span> <span class="o">=</span> <span class="mi">24</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">clock</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">display</span> <span class="o">=</span> <span class="n">display</span>
<span class="bp">self</span><span class="o">.</span><span class="n">clock</span> <span class="o">=</span> <span class="n">clock</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="o">=</span> <span class="kc">False</span>
<div class="viewcode-block" id="TheLoop.install_task"><a class="viewcode-back" href="../../../core.html#joy.vui.core.TheLoop.install_task">[docs]</a> <span class="k">def</span> <span class="nf">install_task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">milliseconds</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Install a task to run every so many milliseconds.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">task_event_id</span> <span class="o">=</span> <span class="n">AVAILABLE_TASK_EVENTS</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">&#39;out of task ids&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_event_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">F</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">time</span><span class="o">.</span><span class="n">set_timer</span><span class="p">(</span><span class="n">task_event_id</span><span class="p">,</span> <span class="n">milliseconds</span><span class="p">)</span>
<span class="k">return</span> <span class="n">task_event_id</span></div>
<div class="viewcode-block" id="TheLoop.remove_task"><a class="viewcode-back" href="../../../core.html#joy.vui.core.TheLoop.remove_task">[docs]</a> <span class="k">def</span> <span class="nf">remove_task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_event_id</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Remove an installed task.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">assert</span> <span class="n">task_event_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">task_event_id</span><span class="p">)</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">time</span><span class="o">.</span><span class="n">set_timer</span><span class="p">(</span><span class="n">task_event_id</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_event_id</span><span class="p">]</span>
<span class="n">AVAILABLE_TASK_EVENTS</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">task_event_id</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Best effort to cancel all running tasks.</span>
<span class="k">for</span> <span class="n">task_event_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">time</span><span class="o">.</span><span class="n">set_timer</span><span class="p">(</span><span class="n">task_event_id</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<div class="viewcode-block" id="TheLoop.run_task"><a class="viewcode-back" href="../../../core.html#joy.vui.core.TheLoop.run_task">[docs]</a> <span class="k">def</span> <span class="nf">run_task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_event_id</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Give a task its time to shine.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_event_id</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">task</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">traceback</span> <span class="o">=</span> <span class="n">format_exc</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove_task</span><span class="p">(</span><span class="n">task_event_id</span><span class="p">)</span>
<span class="nb">print</span> <span class="o">&gt;&gt;</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">traceback</span>
<span class="nb">print</span> <span class="o">&gt;&gt;</span> <span class="n">stderr</span><span class="p">,</span> <span class="s1">&#39;TASK removed due to ERROR&#39;</span><span class="p">,</span> <span class="n">task</span>
<span class="n">open_viewer_on_string</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">traceback</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">)</span></div>
<div class="viewcode-block" id="TheLoop.loop"><a class="viewcode-back" href="../../../core.html#joy.vui.core.TheLoop.loop">[docs]</a> <span class="k">def</span> <span class="nf">loop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> The actual main loop machinery.</span>
<span class="sd"> Maintain a ``running`` flag, pump the PyGame event queue and</span>
<span class="sd"> handle the events (dispatching to the display), tick the clock.</span>
<span class="sd"> When the loop is exited (by clicking the window close button or</span>
<span class="sd"> pressing the ``escape`` key) it broadcasts a ``ShutdownMessage``.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">running</span><span class="p">:</span>
<span class="k">for</span> <span class="n">event</span> <span class="ow">in</span> <span class="n">pygame</span><span class="o">.</span><span class="n">event</span><span class="o">.</span><span class="n">get</span><span class="p">():</span>
<span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">QUIT</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">elif</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KEYUP</span> <span class="ow">and</span> <span class="n">event</span><span class="o">.</span><span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_ESCAPE</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">elif</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">run_task</span><span class="p">(</span><span class="n">event</span><span class="o">.</span><span class="n">type</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">dispatch_event</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">update</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">clock</span><span class="o">.</span><span class="n">tick</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">FRAME_RATE</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">ShutdownMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span></div></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,604 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.vui.display &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.vui.display</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="c1">#</span>
<span class="c1"># Copyright © 2019 Simon Forman</span>
<span class="c1">#</span>
<span class="c1"># This file is part of Thun</span>
<span class="c1">#</span>
<span class="c1"># Thun is free software: you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># Thun is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with Thun. If not see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">Display</span>
<span class="sd">=================</span>
<span class="sd">This module implements a simple visual display system modeled on Oberon.</span>
<span class="sd">Refer to Chapter 4 of the Project Oberon book for more information.</span>
<span class="sd">There is a Display object that manages a pygame surface and N vertical</span>
<span class="sd">tracks each of which manages zero or more viewers.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">copy</span> <span class="k">import</span> <span class="n">copy</span>
<span class="kn">from</span> <span class="nn">sys</span> <span class="k">import</span> <span class="n">stderr</span>
<span class="kn">from</span> <span class="nn">traceback</span> <span class="k">import</span> <span class="n">format_exc</span>
<span class="kn">import</span> <span class="nn">pygame</span>
<span class="kn">from</span> <span class="nn">.core</span> <span class="k">import</span> <span class="p">(</span>
<span class="n">open_viewer_on_string</span><span class="p">,</span>
<span class="n">GREY</span><span class="p">,</span>
<span class="n">MOUSE_EVENTS</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">.viewer</span> <span class="k">import</span> <span class="n">Viewer</span>
<span class="kn">from</span> <span class="nn">joy.vui</span> <span class="k">import</span> <span class="n">text_viewer</span>
<div class="viewcode-block" id="Display"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display">[docs]</a><span class="k">class</span> <span class="nc">Display</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Manage tracks and viewers on a screen (Pygame surface.)</span>
<span class="sd"> The size and number of tracks are defined by passing in at least two</span>
<span class="sd"> ratios, e.g. Display(screen, 1, 4, 4) would create three tracks, one</span>
<span class="sd"> small one on the left and two larger ones of the same size, each four</span>
<span class="sd"> times wider than the left one.</span>
<span class="sd"> All tracks take up the whole height of the display screen. Tracks</span>
<span class="sd"> manage zero or more Viewers. When you &quot;grow&quot; a viewer a new track is</span>
<span class="sd"> created that overlays or hides one or two existing tracks, and when</span>
<span class="sd"> the last viewer in an overlay track is closed the track closes too</span>
<span class="sd"> and reveals the hidden tracks (and their viewers, if any.)</span>
<span class="sd"> In order to facilitate command underlining while mouse dragging the</span>
<span class="sd"> lookup parameter must be a function that accepts a string and returns</span>
<span class="sd"> a Boolean indicating whether that string is a valid Joy function name.</span>
<span class="sd"> Typically you pass in the __contains__ method of the Joy dict. This</span>
<span class="sd"> is a case of breaking &quot;loose coupling&quot; to gain efficiency, as otherwise</span>
<span class="sd"> we would have to e.g. send some sort of lookup message to the</span>
<span class="sd"> World context object, going through the whole Display.broadcast()</span>
<span class="sd"> machinery, etc. Not something you want to do on each MOUSEMOTION</span>
<span class="sd"> event.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">screen</span><span class="p">,</span> <span class="n">lookup</span><span class="p">,</span> <span class="o">*</span><span class="n">track_ratios</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">screen</span> <span class="o">=</span> <span class="n">screen</span>
<span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">=</span> <span class="n">screen</span><span class="o">.</span><span class="n">get_width</span><span class="p">(),</span> <span class="n">screen</span><span class="o">.</span><span class="n">get_height</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lookup</span> <span class="o">=</span> <span class="n">lookup</span>
<span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tracks</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># (x, track)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">handlers</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Non-viewers that should receive messages.</span>
<span class="c1"># Create the tracks.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">track_ratios</span><span class="p">:</span> <span class="n">track_ratios</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span>
<span class="n">x</span><span class="p">,</span> <span class="n">total</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">sum</span><span class="p">(</span><span class="n">track_ratios</span><span class="p">)</span>
<span class="k">for</span> <span class="n">ratio</span> <span class="ow">in</span> <span class="n">track_ratios</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
<span class="n">track_width</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">*</span> <span class="n">ratio</span> <span class="o">/</span> <span class="n">total</span>
<span class="k">assert</span> <span class="n">track_width</span> <span class="o">&gt;=</span> <span class="mi">10</span> <span class="c1"># minimum width 10 pixels</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_open_track</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">track_width</span><span class="p">)</span>
<span class="n">x</span> <span class="o">+=</span> <span class="n">track_width</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_open_track</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">-</span> <span class="n">x</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_open_track</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">w</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Helper function to create the pygame surface and Track.&#39;&#39;&#39;</span>
<span class="n">track_surface</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">screen</span><span class="o">.</span><span class="n">subsurface</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">Track</span><span class="p">(</span><span class="n">track_surface</span><span class="p">)))</span>
<div class="viewcode-block" id="Display.open_viewer"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.open_viewer">[docs]</a> <span class="k">def</span> <span class="nf">open_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">class_</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Open a viewer of class_ at the x, y location on the display,</span>
<span class="sd"> return the viewer.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">track</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_track_at</span><span class="p">(</span><span class="n">x</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">V</span> <span class="o">=</span> <span class="n">track</span><span class="o">.</span><span class="n">open_viewer</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">class_</span><span class="p">)</span>
<span class="n">V</span><span class="o">.</span><span class="n">focus</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="n">V</span></div>
<div class="viewcode-block" id="Display.close_viewer"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.close_viewer">[docs]</a> <span class="k">def</span> <span class="nf">close_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Close the viewer.&#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">x</span><span class="p">,</span> <span class="n">track</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span>
<span class="k">if</span> <span class="n">track</span><span class="o">.</span><span class="n">close_viewer</span><span class="p">(</span><span class="n">viewer</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">track</span><span class="o">.</span><span class="n">viewers</span> <span class="ow">and</span> <span class="n">track</span><span class="o">.</span><span class="n">hiding</span><span class="p">:</span>
<span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="o">.</span><span class="n">index</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">track</span><span class="o">.</span><span class="n">hiding</span>
<span class="k">assert</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">)</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">exposed_track</span> <span class="ow">in</span> <span class="n">track</span><span class="o">.</span><span class="n">hiding</span><span class="p">:</span>
<span class="n">exposed_track</span><span class="o">.</span><span class="n">redraw</span><span class="p">()</span>
<span class="k">if</span> <span class="n">viewer</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">break</span></div>
<div class="viewcode-block" id="Display.change_viewer"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.change_viewer">[docs]</a> <span class="k">def</span> <span class="nf">change_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">relative</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Adjust the top of the viewer to a new y within the boundaries of</span>
<span class="sd"> its neighbors.</span>
<span class="sd"> If relative is False new_y should be in screen coords, else new_y</span>
<span class="sd"> should be relative to the top of the viewer.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">track</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span>
<span class="k">if</span> <span class="n">track</span><span class="o">.</span><span class="n">change_viewer</span><span class="p">(</span><span class="n">viewer</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">relative</span><span class="p">):</span>
<span class="k">break</span></div>
<div class="viewcode-block" id="Display.grow_viewer"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.grow_viewer">[docs]</a> <span class="k">def</span> <span class="nf">grow_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Cause the viewer to take up its whole track or, if it does</span>
<span class="sd"> already, take up another track, up to the whole screen.</span>
<span class="sd"> This is the inverse of closing a viewer. &quot;Growing&quot; a viewer</span>
<span class="sd"> actually creates a new copy and a new track to hold it. The old</span>
<span class="sd"> tracks and viewers are retained, and they get restored when the</span>
<span class="sd"> covering track closes, which happens automatically when the last</span>
<span class="sd"> viewer in the covering track is closed.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">x</span><span class="p">,</span> <span class="n">track</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">V</span> <span class="ow">in</span> <span class="n">track</span><span class="o">.</span><span class="n">viewers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">V</span> <span class="ow">is</span> <span class="n">viewer</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_grow_viewer</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">,</span> <span class="n">viewer</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">_grow_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Helper function to &quot;grow&quot; a viewer.&#39;&#39;&#39;</span>
<span class="n">new_viewer</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">viewer</span><span class="o">.</span><span class="n">h</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span><span class="p">:</span>
<span class="c1"># replace the track with a new track that contains</span>
<span class="c1"># a copy of the viewer at full height.</span>
<span class="n">new_track</span> <span class="o">=</span> <span class="n">Track</span><span class="p">(</span><span class="n">track</span><span class="o">.</span><span class="n">surface</span><span class="p">)</span> <span class="c1"># Reuse it, why not?</span>
<span class="n">new_viewer</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="n">viewer</span><span class="p">)</span>
<span class="n">new_track</span><span class="o">.</span><span class="n">_grow_by</span><span class="p">(</span><span class="n">new_viewer</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">-</span> <span class="n">viewer</span><span class="o">.</span><span class="n">h</span><span class="p">)</span>
<span class="n">new_track</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">new_viewer</span><span class="p">))</span>
<span class="n">new_track</span><span class="o">.</span><span class="n">hiding</span> <span class="o">=</span> <span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">)]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="o">.</span><span class="n">index</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">))]</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">new_track</span>
<span class="k">elif</span> <span class="n">viewer</span><span class="o">.</span><span class="n">w</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">:</span>
<span class="c1"># replace two tracks</span>
<span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="o">.</span><span class="n">index</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span> <span class="c1"># prefer the one on the right</span>
<span class="n">xx</span><span class="p">,</span> <span class="n">xtrack</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="n">i</span> <span class="o">-=</span> <span class="mi">1</span> <span class="c1"># okay, the one on the left</span>
<span class="n">xx</span><span class="p">,</span> <span class="n">xtrack</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="n">hiding</span> <span class="o">=</span> <span class="p">[(</span><span class="n">xx</span><span class="p">,</span> <span class="n">xtrack</span><span class="p">),</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">)]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">hiding</span> <span class="o">=</span> <span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="n">track</span><span class="p">),</span> <span class="p">(</span><span class="n">xx</span><span class="p">,</span> <span class="n">xtrack</span><span class="p">)]</span>
<span class="c1"># We know there has to be at least one other track because it</span>
<span class="c1"># there weren&#39;t then that implies that the one track takes up</span>
<span class="c1"># the whole display screen (the only way you can get just one</span>
<span class="c1"># track is by growing a viewer to cover the whole screen.)</span>
<span class="c1"># Ergo, viewer.w == self.w, so this branch doesn&#39;t run.</span>
<span class="n">new_x</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">xx</span><span class="p">)</span>
<span class="n">new_w</span> <span class="o">=</span> <span class="n">track</span><span class="o">.</span><span class="n">w</span> <span class="o">+</span> <span class="n">xtrack</span><span class="o">.</span><span class="n">w</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">new_x</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">new_w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span>
<span class="n">new_track</span> <span class="o">=</span> <span class="n">Track</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">screen</span><span class="o">.</span><span class="n">subsurface</span><span class="p">(</span><span class="n">r</span><span class="p">))</span>
<span class="n">new_viewer</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="n">viewer</span><span class="p">)</span>
<span class="n">r</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">new_w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span>
<span class="n">new_viewer</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="n">new_track</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">subsurface</span><span class="p">(</span><span class="n">r</span><span class="p">))</span>
<span class="n">new_track</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">new_viewer</span><span class="p">))</span>
<span class="n">new_track</span><span class="o">.</span><span class="n">hiding</span> <span class="o">=</span> <span class="n">hiding</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="p">[(</span><span class="n">new_x</span><span class="p">,</span> <span class="n">new_track</span><span class="p">)]</span>
<span class="n">new_viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">return</span> <span class="n">new_viewer</span>
<span class="k">def</span> <span class="nf">_move_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">to</span><span class="p">,</span> <span class="n">rel_y</span><span class="p">,</span> <span class="n">viewer</span><span class="p">,</span> <span class="n">_x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Helper function to move (really copy) a viewer to a new location.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">to</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">rel_y</span><span class="p">)</span>
<span class="n">new_viewer</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="n">viewer</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">to</span><span class="p">,</span> <span class="n">Track</span><span class="p">):</span>
<span class="n">to</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">T</span> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">T</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">V</span> <span class="ow">in</span> <span class="n">T</span><span class="o">.</span><span class="n">viewers</span>
<span class="k">if</span> <span class="n">V</span> <span class="ow">is</span> <span class="n">to</span><span class="p">)</span>
<span class="n">new_viewer</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="n">to</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">subsurface</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">to</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">)))</span>
<span class="n">to</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">y</span><span class="p">,</span> <span class="n">new_viewer</span><span class="p">))</span>
<span class="n">to</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span> <span class="c1"># bisect.insort() would be overkill here.</span>
<span class="n">new_viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">close_viewer</span><span class="p">(</span><span class="n">viewer</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_track_at</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return the track at x along with the track-relative x coordinate,</span>
<span class="sd"> raise ValueError if x is off-screen.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">track_x</span><span class="p">,</span> <span class="n">track</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span>
<span class="k">if</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">track_x</span> <span class="o">+</span> <span class="n">track</span><span class="o">.</span><span class="n">w</span><span class="p">:</span>
<span class="k">return</span> <span class="n">track</span><span class="p">,</span> <span class="n">x</span> <span class="o">-</span> <span class="n">track_x</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;x outside display: </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">x</span><span class="p">,))</span>
<div class="viewcode-block" id="Display.at"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.at">[docs]</a> <span class="k">def</span> <span class="nf">at</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return the viewer (which can be a Track) at the x, y location,</span>
<span class="sd"> along with the relative-to-viewer-surface x and y coordinates.</span>
<span class="sd"> If there is no viewer at the location the Track will be returned</span>
<span class="sd"> instead.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">track</span><span class="p">,</span> <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_track_at</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">viewer</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">track</span><span class="o">.</span><span class="n">viewer_at</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
<span class="k">return</span> <span class="n">viewer</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span></div>
<div class="viewcode-block" id="Display.iter_viewers"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.iter_viewers">[docs]</a> <span class="k">def</span> <span class="nf">iter_viewers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Iterate through all viewers yielding (viewer, x, y) three-tuples.</span>
<span class="sd"> The x and y coordinates are screen pixels of the top-left corner</span>
<span class="sd"> of the viewer.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">x</span><span class="p">,</span> <span class="n">T</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span>
<span class="k">for</span> <span class="n">y</span><span class="p">,</span> <span class="n">V</span> <span class="ow">in</span> <span class="n">T</span><span class="o">.</span><span class="n">viewers</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">V</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span></div>
<div class="viewcode-block" id="Display.done_resizing"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.done_resizing">[docs]</a> <span class="k">def</span> <span class="nf">done_resizing</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Helper method called directly by ``MenuViewer.mouse_up()`` to (hackily)</span>
<span class="sd"> update the display when done resizing a viewer.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">track</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span> <span class="c1"># This should be done by a Message?</span>
<span class="k">if</span> <span class="n">track</span><span class="o">.</span><span class="n">resizing_viewer</span><span class="p">:</span>
<span class="n">track</span><span class="o">.</span><span class="n">resizing_viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="n">track</span><span class="o">.</span><span class="n">resizing_viewer</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">break</span></div>
<div class="viewcode-block" id="Display.broadcast"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.broadcast">[docs]</a> <span class="k">def</span> <span class="nf">broadcast</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Broadcast a message to all viewers (except the sender) and all</span>
<span class="sd"> registered handlers.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">track</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span>
<span class="n">track</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">for</span> <span class="n">handler</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">handlers</span><span class="p">:</span>
<span class="n">handler</span><span class="p">(</span><span class="n">message</span><span class="p">)</span></div>
<div class="viewcode-block" id="Display.redraw"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.redraw">[docs]</a> <span class="k">def</span> <span class="nf">redraw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Redraw all tracks (which will redraw all viewers.)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">track</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tracks</span><span class="p">:</span>
<span class="n">track</span><span class="o">.</span><span class="n">redraw</span><span class="p">()</span></div>
<div class="viewcode-block" id="Display.focus"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.focus">[docs]</a> <span class="k">def</span> <span class="nf">focus</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Set system focus to a given viewer (or no viewer if a track.)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">viewer</span><span class="p">,</span> <span class="n">Track</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="o">.</span><span class="n">unfocus</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">viewer</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="o">.</span><span class="n">unfocus</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span> <span class="o">=</span> <span class="n">viewer</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">focus</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
<div class="viewcode-block" id="Display.dispatch_event"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.dispatch_event">[docs]</a> <span class="k">def</span> <span class="nf">dispatch_event</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Display event handling.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="ow">in</span> <span class="p">{</span><span class="n">pygame</span><span class="o">.</span><span class="n">KEYUP</span><span class="p">,</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KEYDOWN</span><span class="p">}:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_keyboard_event</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="ow">in</span> <span class="n">MOUSE_EVENTS</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_mouse_event</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="o">&gt;&gt;</span> <span class="n">stderr</span><span class="p">,</span> <span class="p">(</span>
<span class="s1">&#39;received event </span><span class="si">%s</span><span class="s1"> Use pygame.event.set_allowed().&#39;</span>
<span class="o">%</span> <span class="n">pygame</span><span class="o">.</span><span class="n">event</span><span class="o">.</span><span class="n">event_name</span><span class="p">(</span><span class="n">event</span><span class="o">.</span><span class="n">type</span><span class="p">)</span>
<span class="p">)</span>
<span class="c1"># Catch all exceptions and open a viewer.</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">format_exc</span><span class="p">()</span>
<span class="nb">print</span> <span class="o">&gt;&gt;</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">err</span> <span class="c1"># To be safe just print it right away.</span>
<span class="n">open_viewer_on_string</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">err</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">broadcast</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">_keyboard_event</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
<span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_PAUSE</span> <span class="ow">and</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KEYUP</span><span class="p">:</span>
<span class="c1"># At least on my keyboard the break/pause key sends K_PAUSE.</span>
<span class="c1"># The main use of this is to open a TextViewer if you</span>
<span class="c1"># accidentally close all the viewers, so you can recover.</span>
<span class="k">raise</span> <span class="ne">KeyboardInterrupt</span><span class="p">(</span><span class="s1">&#39;break&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KEYUP</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="o">.</span><span class="n">key_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">event</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KEYDOWN</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="o">.</span><span class="n">key_down</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="o">.</span><span class="n">unicode</span><span class="p">,</span> <span class="n">event</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">event</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_mouse_event</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
<span class="n">V</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="o">*</span><span class="n">event</span><span class="o">.</span><span class="n">pos</span><span class="p">)</span>
<span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">MOUSEMOTION</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">V</span><span class="p">,</span> <span class="n">Track</span><span class="p">):</span>
<span class="n">V</span><span class="o">.</span><span class="n">mouse_motion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="n">event</span><span class="o">.</span><span class="n">rel</span> <span class="o">+</span> <span class="n">event</span><span class="o">.</span><span class="n">buttons</span><span class="p">))</span>
<span class="k">elif</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">MOUSEBUTTONDOWN</span><span class="p">:</span>
<span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">button</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">focus</span><span class="p">(</span><span class="n">V</span><span class="p">)</span>
<span class="n">V</span><span class="o">.</span><span class="n">mouse_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">event</span><span class="o">.</span><span class="n">button</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">assert</span> <span class="n">event</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">MOUSEBUTTONUP</span>
<span class="c1"># Check for moving viewer.</span>
<span class="k">if</span> <span class="p">(</span><span class="n">event</span><span class="o">.</span><span class="n">button</span> <span class="o">==</span> <span class="mi">2</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span>
<span class="ow">and</span> <span class="n">V</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span>
<span class="ow">and</span> <span class="n">V</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span> <span class="o">&lt;</span> <span class="n">y</span> <span class="o">&lt;</span> <span class="n">V</span><span class="o">.</span><span class="n">h</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span>
<span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_move_viewer</span><span class="p">(</span><span class="n">V</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">focused_viewer</span><span class="p">,</span> <span class="o">*</span><span class="n">event</span><span class="o">.</span><span class="n">pos</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">V</span><span class="o">.</span><span class="n">mouse_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">event</span><span class="o">.</span><span class="n">button</span><span class="p">)</span>
<div class="viewcode-block" id="Display.init_text"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Display.init_text">[docs]</a> <span class="k">def</span> <span class="nf">init_text</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pt</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Open and return a ``TextViewer`` on a given file (which must be present</span>
<span class="sd"> in the ``JOYHOME`` directory.)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">viewer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_viewer</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">text_viewer</span><span class="o">.</span><span class="n">TextViewer</span><span class="p">)</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">content_id</span><span class="p">,</span> <span class="n">viewer</span><span class="o">.</span><span class="n">lines</span> <span class="o">=</span> <span class="n">pt</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">return</span> <span class="n">viewer</span></div></div>
<div class="viewcode-block" id="Track"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track">[docs]</a><span class="k">class</span> <span class="nc">Track</span><span class="p">(</span><span class="n">Viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Manage a vertical strip of the display, and the viewers on it.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="n">Viewer</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">viewers</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># (y, viewer)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">hiding</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing_viewer</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<div class="viewcode-block" id="Track.split"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.split">[docs]</a> <span class="k">def</span> <span class="nf">split</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Split the Track at the y coordinate and return the height</span>
<span class="sd"> available for a new viewer. Tracks manage a vertical strip of</span>
<span class="sd"> the display screen so they don&#39;t resize their surface when split.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span> <span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span>
<span class="k">assert</span> <span class="n">h</span> <span class="o">&gt;</span> <span class="n">y</span>
<span class="k">return</span> <span class="n">h</span> <span class="o">-</span> <span class="n">y</span></div>
<div class="viewcode-block" id="Track.draw"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.draw">[docs]</a> <span class="k">def</span> <span class="nf">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Draw the track onto its surface, clearing all content.</span>
<span class="sd"> If rect is passed only draw to that area. This supports e.g.</span>
<span class="sd"> closing a viewer that then exposes part of the track.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span><span class="n">GREY</span><span class="p">,</span> <span class="n">rect</span><span class="o">=</span><span class="n">rect</span><span class="p">)</span></div>
<div class="viewcode-block" id="Track.viewer_at"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.viewer_at">[docs]</a> <span class="k">def</span> <span class="nf">viewer_at</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return the viewer at y along with the viewer-relative y coordinate,</span>
<span class="sd"> if there&#39;s no viewer at y return this track and y.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">viewer_y</span><span class="p">,</span> <span class="n">viewer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">viewer_y</span> <span class="o">&lt;</span> <span class="n">y</span> <span class="o">&lt;=</span> <span class="n">viewer_y</span> <span class="o">+</span> <span class="n">viewer</span><span class="o">.</span><span class="n">h</span><span class="p">:</span>
<span class="k">return</span> <span class="n">viewer</span><span class="p">,</span> <span class="n">y</span> <span class="o">-</span> <span class="n">viewer_y</span>
<span class="k">return</span> <span class="bp">self</span><span class="p">,</span> <span class="n">y</span></div>
<div class="viewcode-block" id="Track.open_viewer"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.open_viewer">[docs]</a> <span class="k">def</span> <span class="nf">open_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">class_</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Open and return a viewer of class at y.&#39;&#39;&#39;</span>
<span class="c1"># Todo: if y coincides with some other viewer&#39;s y replace it.</span>
<span class="n">viewer</span><span class="p">,</span> <span class="n">viewer_y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewer_at</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">viewer</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">viewer_y</span><span class="p">)</span>
<span class="n">new_viewer</span> <span class="o">=</span> <span class="n">class_</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">subsurface</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">)))</span>
<span class="n">new_viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">y</span><span class="p">,</span> <span class="n">new_viewer</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span> <span class="c1"># Could use bisect module but how many</span>
<span class="c1"># viewers will you ever have?</span>
<span class="k">return</span> <span class="n">new_viewer</span></div>
<div class="viewcode-block" id="Track.close_viewer"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.close_viewer">[docs]</a> <span class="k">def</span> <span class="nf">close_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Close the viewer, reuse the freed space.&#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">y</span><span class="p">,</span> <span class="n">V</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">V</span> <span class="ow">is</span> <span class="n">viewer</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_close_viewer</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">V</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
<span class="k">def</span> <span class="nf">_close_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Helper function to do the actual closing.&#39;&#39;&#39;</span>
<span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">index</span><span class="p">((</span><span class="n">y</span><span class="p">,</span> <span class="n">viewer</span><span class="p">))</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="k">if</span> <span class="n">i</span><span class="p">:</span> <span class="c1"># The previous viewer gets the space.</span>
<span class="n">previous_y</span><span class="p">,</span> <span class="n">previous_viewer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_grow_by</span><span class="p">(</span><span class="n">previous_viewer</span><span class="p">,</span> <span class="n">previous_y</span><span class="p">,</span> <span class="n">viewer</span><span class="o">.</span><span class="n">h</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># This track gets the space.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="n">viewer</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">get_height</span><span class="p">()))</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_grow_by</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">h</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Grow a viewer (located at y) by height h.</span>
<span class="sd"> This might seem like it should be a method of the viewer, but</span>
<span class="sd"> the viewer knows nothing of its own y location on the screen nor</span>
<span class="sd"> the parent track&#39;s surface (to make a new subsurface) so it has</span>
<span class="sd"> to be a method of the track, which has both.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">viewer</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">get_height</span><span class="p">()</span> <span class="o">+</span> <span class="n">h</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">surface</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">subsurface</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="c1"># subsurface rectangle outside surface area</span>
<span class="k">pass</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="n">surface</span><span class="p">)</span>
<span class="k">if</span> <span class="n">h</span> <span class="o">&lt;=</span> <span class="n">viewer</span><span class="o">.</span><span class="n">last_touch</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="n">viewer</span><span class="o">.</span><span class="n">last_touch</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<div class="viewcode-block" id="Track.change_viewer"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.change_viewer">[docs]</a> <span class="k">def</span> <span class="nf">change_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">,</span> <span class="n">new_y</span><span class="p">,</span> <span class="n">relative</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Adjust the top of the viewer to a new y within the boundaries of</span>
<span class="sd"> its neighbors.</span>
<span class="sd"> If relative is False new_y should be in screen coords, else new_y</span>
<span class="sd"> should be relative to the top of the viewer.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">old_y</span><span class="p">,</span> <span class="n">V</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">V</span> <span class="ow">is</span> <span class="n">viewer</span><span class="p">:</span>
<span class="k">if</span> <span class="n">relative</span><span class="p">:</span> <span class="n">new_y</span> <span class="o">+=</span> <span class="n">old_y</span>
<span class="k">if</span> <span class="n">new_y</span> <span class="o">!=</span> <span class="n">old_y</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_change_viewer</span><span class="p">(</span><span class="n">new_y</span><span class="p">,</span> <span class="n">old_y</span><span class="p">,</span> <span class="n">V</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
<span class="k">def</span> <span class="nf">_change_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_y</span><span class="p">,</span> <span class="n">old_y</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="n">new_y</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">h</span><span class="p">,</span> <span class="n">new_y</span><span class="p">))</span>
<span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="o">.</span><span class="n">index</span><span class="p">((</span><span class="n">old_y</span><span class="p">,</span> <span class="n">viewer</span><span class="p">))</span>
<span class="k">if</span> <span class="n">new_y</span> <span class="o">&lt;</span> <span class="n">old_y</span><span class="p">:</span> <span class="c1"># Enlarge self, shrink upper neighbor.</span>
<span class="k">if</span> <span class="n">i</span><span class="p">:</span>
<span class="n">previous_y</span><span class="p">,</span> <span class="n">previous_viewer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="n">new_y</span> <span class="o">-</span> <span class="n">previous_y</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">previous_viewer</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">previous_viewer</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">new_y</span> <span class="o">-</span> <span class="n">previous_y</span><span class="p">)</span>
<span class="n">previous_viewer</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing_viewer</span> <span class="o">=</span> <span class="n">previous_viewer</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">old_y</span> <span class="o">-</span> <span class="n">new_y</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_grow_by</span><span class="p">(</span><span class="n">viewer</span><span class="p">,</span> <span class="n">new_y</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># Shink self, enlarge upper neighbor.</span>
<span class="c1"># Enforce invariant.</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">h</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span> <span class="c1"># No next viewer.</span>
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span>
<span class="k">if</span> <span class="n">h</span> <span class="o">-</span> <span class="n">new_y</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span><span class="p">:</span>
<span class="k">return</span>
<span class="c1"># Change the viewer and adjust the upper viewer or track.</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">new_y</span> <span class="o">-</span> <span class="n">old_y</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_grow_by</span><span class="p">(</span><span class="n">viewer</span><span class="p">,</span> <span class="n">new_y</span><span class="p">,</span> <span class="o">-</span><span class="n">h</span><span class="p">)</span> <span class="c1"># grow by negative height!</span>
<span class="k">if</span> <span class="n">i</span><span class="p">:</span>
<span class="n">previous_y</span><span class="p">,</span> <span class="n">previous_viewer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<span class="n">previous_viewer</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_grow_by</span><span class="p">(</span><span class="n">previous_viewer</span><span class="p">,</span> <span class="n">previous_y</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
<span class="n">previous_viewer</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing_viewer</span> <span class="o">=</span> <span class="n">previous_viewer</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="n">old_y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_y</span><span class="p">,</span> <span class="n">viewer</span>
<span class="c1"># self.viewers.sort() # Not necessary, invariant holds.</span>
<span class="k">assert</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">)</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span>
<div class="viewcode-block" id="Track.broadcast"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.broadcast">[docs]</a> <span class="k">def</span> <span class="nf">broadcast</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Broadcast a message to all viewers on this track (except the sender.)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">viewer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">viewer</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">sender</span><span class="p">:</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">handle</span><span class="p">(</span><span class="n">message</span><span class="p">)</span></div>
<div class="viewcode-block" id="Track.redraw"><a class="viewcode-back" href="../../../display.html#joy.vui.display.Track.redraw">[docs]</a> <span class="k">def</span> <span class="nf">redraw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Redraw the track and all of its viewers.&#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">viewer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">viewers</span><span class="p">:</span>
<span class="n">viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span></div></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,274 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.vui.main &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.vui.main</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="c1">#</span>
<span class="c1"># Copyright © 2019 Simon Forman</span>
<span class="c1">#</span>
<span class="c1"># This file is part of Thun</span>
<span class="c1">#</span>
<span class="c1"># Thun is free software: you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># Thun is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with Thun. If not see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">Main Module</span>
<span class="sd">======================================</span>
<span class="sd">Pulls everything together.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">traceback</span>
<span class="kn">import</span> <span class="nn">pygame</span>
<span class="kn">from</span> <span class="nn">joy.library</span> <span class="k">import</span> <span class="n">initialize</span><span class="p">,</span> <span class="n">DefinitionWrapper</span><span class="p">,</span> <span class="n">SimpleFunctionWrapper</span>
<span class="kn">from</span> <span class="nn">joy.vui</span> <span class="k">import</span> <span class="n">core</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">persist_task</span>
<span class="n">FULLSCREEN</span> <span class="o">=</span> <span class="s1">&#39;-f&#39;</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span>
<span class="n">JOY_HOME</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;JOY_HOME&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">JOY_HOME</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">JOY_HOME</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s1">&#39;~/.thun&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isabs</span><span class="p">(</span><span class="n">JOY_HOME</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;what directory?&#39;</span><span class="p">)</span>
<div class="viewcode-block" id="load_definitions"><a class="viewcode-back" href="../../../main.html#joy.vui.main.load_definitions">[docs]</a><span class="k">def</span> <span class="nf">load_definitions</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Load definitions from ``definitions.txt``.&#39;&#39;&#39;</span>
<span class="n">lines</span> <span class="o">=</span> <span class="n">pt</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">&#39;definitions.txt&#39;</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
<span class="k">if</span> <span class="s1">&#39;==&#39;</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
<span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_def</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span></div>
<div class="viewcode-block" id="load_primitives"><a class="viewcode-back" href="../../../main.html#joy.vui.main.load_primitives">[docs]</a><span class="k">def</span> <span class="nf">load_primitives</span><span class="p">(</span><span class="n">home</span><span class="p">,</span> <span class="n">name_space</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Load primitives from ``library.py``.&#39;&#39;&#39;</span>
<span class="n">fn</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">home</span><span class="p">,</span> <span class="s1">&#39;library.py&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
<span class="n">execfile</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="n">name_space</span><span class="p">)</span></div>
<div class="viewcode-block" id="init"><a class="viewcode-back" href="../../../main.html#joy.vui.main.init">[docs]</a><span class="k">def</span> <span class="nf">init</span><span class="p">():</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Initialize the system.</span>
<span class="sd"> </span>
<span class="sd"> * Init PyGame</span>
<span class="sd"> * Create main window</span>
<span class="sd"> * Start the PyGame clock</span>
<span class="sd"> * Set the event mask</span>
<span class="sd"> * Create the PersistTask</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="nb">print</span> <span class="s1">&#39;Initializing Pygame...&#39;</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
<span class="nb">print</span> <span class="s1">&#39;Creating window...&#39;</span>
<span class="k">if</span> <span class="n">FULLSCREEN</span><span class="p">:</span>
<span class="n">screen</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">set_mode</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">screen</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">set_mode</span><span class="p">((</span><span class="mi">1024</span><span class="p">,</span> <span class="mi">768</span><span class="p">))</span>
<span class="n">clock</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">time</span><span class="o">.</span><span class="n">Clock</span><span class="p">()</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">event</span><span class="o">.</span><span class="n">set_allowed</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">event</span><span class="o">.</span><span class="n">set_allowed</span><span class="p">(</span><span class="n">core</span><span class="o">.</span><span class="n">ALLOWED_EVENTS</span><span class="p">)</span>
<span class="n">pt</span> <span class="o">=</span> <span class="n">persist_task</span><span class="o">.</span><span class="n">PersistTask</span><span class="p">(</span><span class="n">JOY_HOME</span><span class="p">)</span>
<span class="k">return</span> <span class="n">screen</span><span class="p">,</span> <span class="n">clock</span><span class="p">,</span> <span class="n">pt</span></div>
<div class="viewcode-block" id="init_context"><a class="viewcode-back" href="../../../main.html#joy.vui.main.init_context">[docs]</a><span class="k">def</span> <span class="nf">init_context</span><span class="p">(</span><span class="n">screen</span><span class="p">,</span> <span class="n">clock</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> More initialization</span>
<span class="sd"> * Create the Joy dictionary</span>
<span class="sd"> * Create the Display</span>
<span class="sd"> * Open the log, menu, and scratch text viewers, and the stack pickle</span>
<span class="sd"> * Start the main loop</span>
<span class="sd"> * Create the World object</span>
<span class="sd"> * Register PersistTask and World message handlers with the Display</span>
<span class="sd"> * Load user function definitions.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">D</span> <span class="o">=</span> <span class="n">initialize</span><span class="p">()</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">display</span><span class="o">.</span><span class="n">Display</span><span class="p">(</span>
<span class="n">screen</span><span class="p">,</span>
<span class="n">D</span><span class="o">.</span><span class="n">__contains__</span><span class="p">,</span>
<span class="o">*</span><span class="p">((</span><span class="mi">144</span> <span class="o">-</span> <span class="mi">89</span><span class="p">,</span> <span class="mi">144</span><span class="p">,</span> <span class="mi">89</span><span class="p">)</span> <span class="k">if</span> <span class="n">FULLSCREEN</span> <span class="k">else</span> <span class="p">(</span><span class="mi">89</span><span class="p">,</span> <span class="mi">144</span><span class="p">))</span>
<span class="p">)</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">init_text</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">&#39;log.txt&#39;</span><span class="p">)</span>
<span class="n">tho</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">init_text</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">h</span> <span class="o">/</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">&#39;menu.txt&#39;</span><span class="p">)</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">init_text</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">w</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">&#39;scratch.txt&#39;</span><span class="p">)</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">TheLoop</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">clock</span><span class="p">)</span>
<span class="n">stack_id</span><span class="p">,</span> <span class="n">stack_holder</span> <span class="o">=</span> <span class="n">pt</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">&#39;stack.pickle&#39;</span><span class="p">)</span>
<span class="n">world</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">World</span><span class="p">(</span><span class="n">stack_id</span><span class="p">,</span> <span class="n">stack_holder</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">broadcast</span><span class="p">,</span> <span class="n">log</span><span class="p">)</span>
<span class="n">loop</span><span class="o">.</span><span class="n">install_task</span><span class="p">(</span><span class="n">pt</span><span class="o">.</span><span class="n">task_run</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="c1"># save files every ten seconds</span>
<span class="n">d</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pt</span><span class="o">.</span><span class="n">handle</span><span class="p">)</span>
<span class="n">d</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">world</span><span class="o">.</span><span class="n">handle</span><span class="p">)</span>
<span class="n">load_definitions</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">locals</span><span class="p">()</span></div>
<div class="viewcode-block" id="error_guard"><a class="viewcode-back" href="../../../main.html#joy.vui.main.error_guard">[docs]</a><span class="k">def</span> <span class="nf">error_guard</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="mi">10</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Run a loop function, retry for ``n`` exceptions.</span>
<span class="sd"> Prints tracebacks on ``sys.stderr``.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">error_count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">error_count</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">loop</span><span class="p">()</span>
<span class="k">break</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">traceback</span><span class="o">.</span><span class="n">print_exc</span><span class="p">(</span><span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
<span class="n">error_count</span> <span class="o">+=</span> <span class="mi">1</span></div>
<div class="viewcode-block" id="FileFaker"><a class="viewcode-back" href="../../../main.html#joy.vui.main.FileFaker">[docs]</a><span class="k">class</span> <span class="nc">FileFaker</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Pretends to be a file object but writes to log instead.&#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log</span> <span class="o">=</span> <span class="n">log</span>
<div class="viewcode-block" id="FileFaker.write"><a class="viewcode-back" href="../../../main.html#joy.vui.main.FileFaker.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Write text to log.&#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">text</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">flush</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="main"><a class="viewcode-back" href="../../../main.html#joy.vui.main.main">[docs]</a><span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">screen</span><span class="p">,</span> <span class="n">clock</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Main function.</span>
<span class="sd"> * Call ``init_context()``</span>
<span class="sd"> * Load primitives</span>
<span class="sd"> * Create an ``evaluate`` function that lets you just eval some Python code</span>
<span class="sd"> * Redirect ``stdout`` to the log using a ``FileFaker`` object, and...</span>
<span class="sd"> * Start the main loop.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">name_space</span> <span class="o">=</span> <span class="n">init_context</span><span class="p">(</span><span class="n">screen</span><span class="p">,</span> <span class="n">clock</span><span class="p">,</span> <span class="n">pt</span><span class="p">)</span>
<span class="n">load_primitives</span><span class="p">(</span><span class="n">pt</span><span class="o">.</span><span class="n">home</span><span class="p">,</span> <span class="n">name_space</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span>
<span class="nd">@SimpleFunctionWrapper</span>
<span class="k">def</span> <span class="nf">evaluate</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Evaluate the Python code text on the top of the stack.&#39;&#39;&#39;</span>
<span class="n">code</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="n">exec</span> <span class="n">code</span> <span class="ow">in</span> <span class="n">name_space</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">return</span> <span class="n">stack</span>
<span class="n">name_space</span><span class="p">[</span><span class="s1">&#39;D&#39;</span><span class="p">][</span><span class="s1">&#39;evaluate&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">evaluate</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">old_stdout</span> <span class="o">=</span> <span class="n">FileFaker</span><span class="p">(</span><span class="n">name_space</span><span class="p">[</span><span class="s1">&#39;log&#39;</span><span class="p">]),</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">error_guard</span><span class="p">(</span><span class="n">name_space</span><span class="p">[</span><span class="s1">&#39;loop&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">loop</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">old_stdout</span>
<span class="k">return</span> <span class="n">name_space</span><span class="p">[</span><span class="s1">&#39;d&#39;</span><span class="p">]</span></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,372 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.vui.persist_task &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.vui.persist_task</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="c1">#</span>
<span class="c1"># Copyright © 2019 Simon Forman</span>
<span class="c1">#</span>
<span class="c1"># This file is part of Thun</span>
<span class="c1">#</span>
<span class="c1"># Thun is free software: you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># Thun is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with Thun. If not see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">Persist Task</span>
<span class="sd">===========================</span>
<span class="sd">This module deals with persisting the &quot;resources&quot; (text files and the</span>
<span class="sd">stack) to the git repo in the ``JOY_HOME`` directory.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">pickle</span><span class="o">,</span> <span class="nn">traceback</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">Counter</span>
<span class="kn">from</span> <span class="nn">dulwich.errors</span> <span class="k">import</span> <span class="n">NotGitRepository</span>
<span class="kn">from</span> <span class="nn">dulwich.repo</span> <span class="k">import</span> <span class="n">Repo</span>
<span class="kn">from</span> <span class="nn">joy.vui</span> <span class="k">import</span> <span class="n">core</span><span class="p">,</span> <span class="n">init_joy_home</span>
<div class="viewcode-block" id="open_repo"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.open_repo">[docs]</a><span class="k">def</span> <span class="nf">open_repo</span><span class="p">(</span><span class="n">repo_dir</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">initialize</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Open, or create, and return a Dulwich git repo object for the given</span>
<span class="sd"> directory. If the dir path doesn&#39;t exist it will be created. If it</span>
<span class="sd"> does exist but isn&#39;t a repo the result depends on the ``initialize``</span>
<span class="sd"> argument. If it is ``False`` (the default) a ``NotGitRepository``</span>
<span class="sd"> exception is raised, otherwise ``git init`` is effected in the dir.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">,</span> <span class="mi">0700</span><span class="p">)</span>
<span class="k">return</span> <span class="n">init_repo</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Repo</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">)</span>
<span class="k">except</span> <span class="n">NotGitRepository</span><span class="p">:</span>
<span class="k">if</span> <span class="n">initialize</span><span class="p">:</span>
<span class="k">return</span> <span class="n">init_repo</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">)</span>
<span class="k">raise</span></div>
<div class="viewcode-block" id="init_repo"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.init_repo">[docs]</a><span class="k">def</span> <span class="nf">init_repo</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Initialize a git repository in the directory. Stage and commit all</span>
<span class="sd"> files (toplevel, not those in subdirectories if any) in the dir.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">repo</span> <span class="o">=</span> <span class="n">Repo</span><span class="o">.</span><span class="n">init</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">)</span>
<span class="n">init_joy_home</span><span class="o">.</span><span class="n">initialize</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">)</span>
<span class="n">repo</span><span class="o">.</span><span class="n">stage</span><span class="p">([</span>
<span class="n">fn</span>
<span class="k">for</span> <span class="n">fn</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">repo_dir</span><span class="p">,</span> <span class="n">fn</span><span class="p">))</span>
<span class="p">])</span>
<span class="n">repo</span><span class="o">.</span><span class="n">do_commit</span><span class="p">(</span><span class="s1">&#39;Initial commit.&#39;</span><span class="p">,</span> <span class="n">committer</span><span class="o">=</span><span class="n">core</span><span class="o">.</span><span class="n">COMMITTER</span><span class="p">)</span>
<span class="k">return</span> <span class="n">repo</span></div>
<div class="viewcode-block" id="make_repo_relative_path_maker"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.make_repo_relative_path_maker">[docs]</a><span class="k">def</span> <span class="nf">make_repo_relative_path_maker</span><span class="p">(</span><span class="n">repo</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Helper function to return a function that returns a path given a path,</span>
<span class="sd"> that&#39;s relative to the repository.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">controldir</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">repo_relative_path</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">commonprefix</span><span class="p">((</span><span class="n">c</span><span class="p">,</span> <span class="n">path</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">repo_relative_path</span></div>
<div class="viewcode-block" id="Resource"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.Resource">[docs]</a><span class="k">class</span> <span class="nc">Resource</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Handle the content of a text files as a list of lines, deal with</span>
<span class="sd"> saving it and staging the changes to a repo.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">repo_relative_filename</span><span class="p">,</span> <span class="n">thing</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span>
<span class="bp">self</span><span class="o">.</span><span class="n">repo_relative_filename</span> <span class="o">=</span> <span class="n">repo_relative_filename</span>
<span class="bp">self</span><span class="o">.</span><span class="n">thing</span> <span class="o">=</span> <span class="n">thing</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_from_file</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_from_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_to_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">thing</span><span class="p">:</span>
<span class="nb">print</span> <span class="o">&gt;&gt;</span> <span class="n">f</span><span class="p">,</span> <span class="n">line</span>
<div class="viewcode-block" id="Resource.persist"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.Resource.persist">[docs]</a> <span class="k">def</span> <span class="nf">persist</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">repo</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Save the lines to the file and stage the file in the repo.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="mi">0600</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_to_file</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="n">os</span><span class="o">.</span><span class="n">fsync</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span>
<span class="c1"># For goodness&#39;s sake, write it to the disk already!</span>
<span class="n">repo</span><span class="o">.</span><span class="n">stage</span><span class="p">([</span><span class="bp">self</span><span class="o">.</span><span class="n">repo_relative_filename</span><span class="p">])</span></div></div>
<div class="viewcode-block" id="PickledResource"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PickledResource">[docs]</a><span class="k">class</span> <span class="nc">PickledResource</span><span class="p">(</span><span class="n">Resource</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> A ``Resource`` subclass that uses ``pickle`` on its file/thing.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">_from_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)]</span>
<span class="k">def</span> <span class="nf">_to_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">thing</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">)</span></div>
<div class="viewcode-block" id="PersistTask"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask">[docs]</a><span class="k">class</span> <span class="nc">PersistTask</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> This class deals with saving changes to the git repo.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">LIMIT</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">MAX_SAVE</span> <span class="o">=</span> <span class="mi">10</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">home</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">home</span> <span class="o">=</span> <span class="n">home</span>
<span class="bp">self</span><span class="o">.</span><span class="n">repo</span> <span class="o">=</span> <span class="n">open_repo</span><span class="p">(</span><span class="n">home</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_r</span> <span class="o">=</span> <span class="n">make_repo_relative_path_maker</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">repo</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">counter</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">store</span> <span class="o">=</span> <span class="p">{}</span>
<div class="viewcode-block" id="PersistTask.open"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.open">[docs]</a> <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Look up the named file in home and return its content_id and data.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">fn</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">home</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="n">content_id</span> <span class="o">=</span> <span class="n">name</span> <span class="c1"># hash(fn)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">resource</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">[</span><span class="n">content_id</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="n">R</span> <span class="o">=</span> <span class="n">PickledResource</span> <span class="k">if</span> <span class="n">name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;.pickle&#39;</span><span class="p">)</span> <span class="k">else</span> <span class="n">Resource</span>
<span class="n">resource</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">[</span><span class="n">content_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">R</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_r</span><span class="p">(</span><span class="n">fn</span><span class="p">))</span>
<span class="k">return</span> <span class="n">content_id</span><span class="p">,</span> <span class="n">resource</span><span class="o">.</span><span class="n">thing</span></div>
<div class="viewcode-block" id="PersistTask.handle"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.handle">[docs]</a> <span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Handle messages, dispatch to ``handle_FOO()`` methods.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">core</span><span class="o">.</span><span class="n">OpenMessage</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">handle_open</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">core</span><span class="o">.</span><span class="n">ModifyMessage</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">handle_modify</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">core</span><span class="o">.</span><span class="n">PersistMessage</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">handle_persist</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">core</span><span class="o">.</span><span class="n">ShutdownMessage</span><span class="p">):</span>
<span class="k">for</span> <span class="n">content_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">counter</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">[</span><span class="n">content_id</span><span class="p">]</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">repo</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">commit</span><span class="p">(</span><span class="s1">&#39;shutdown&#39;</span><span class="p">)</span></div>
<div class="viewcode-block" id="PersistTask.handle_open"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.handle_open">[docs]</a> <span class="k">def</span> <span class="nf">handle_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Foo.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">message</span><span class="o">.</span><span class="n">content_id</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">thing</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">message</span><span class="o">.</span><span class="n">traceback</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">()</span>
<span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">ERROR</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">message</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">SUCCESS</span></div>
<div class="viewcode-block" id="PersistTask.handle_modify"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.handle_modify">[docs]</a> <span class="k">def</span> <span class="nf">handle_modify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Foo.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">content_id</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">details</span><span class="p">[</span><span class="s1">&#39;content_id&#39;</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">content_id</span><span class="p">:</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">counter</span><span class="p">[</span><span class="n">content_id</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">counter</span><span class="p">[</span><span class="n">content_id</span><span class="p">]</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">LIMIT</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="n">content_id</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">commit</span><span class="p">(</span><span class="s1">&#39;due to activity&#39;</span><span class="p">)</span></div>
<div class="viewcode-block" id="PersistTask.handle_persist"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.handle_persist">[docs]</a> <span class="k">def</span> <span class="nf">handle_persist</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Foo.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">resource</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">[</span><span class="n">message</span><span class="o">.</span><span class="n">content_id</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="n">resource</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handle_persist_new</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="n">resource</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">repo</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">commit</span><span class="p">(</span><span class="s1">&#39;by request from </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">sender</span><span class="p">,))</span></div>
<div class="viewcode-block" id="PersistTask.handle_persist_new"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.handle_persist_new">[docs]</a> <span class="k">def</span> <span class="nf">handle_persist_new</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Foo.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">content_id</span>
<span class="n">check_filename</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">fn</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">home</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="n">thing</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">details</span><span class="p">[</span><span class="s1">&#39;thing&#39;</span><span class="p">]</span>
<span class="n">R</span> <span class="o">=</span> <span class="n">PickledResource</span> <span class="k">if</span> <span class="n">name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;.pickle&#39;</span><span class="p">)</span> <span class="k">else</span> <span class="n">Resource</span> <span class="c1"># !!! refactor!</span>
<span class="n">resource</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">R</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_r</span><span class="p">(</span><span class="n">fn</span><span class="p">),</span> <span class="n">thing</span><span class="p">)</span>
<span class="k">return</span> <span class="n">resource</span></div>
<div class="viewcode-block" id="PersistTask.persist"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.persist">[docs]</a> <span class="k">def</span> <span class="nf">persist</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content_id</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Persist a resource.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">counter</span><span class="p">[</span><span class="n">content_id</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">[</span><span class="n">content_id</span><span class="p">]</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">repo</span><span class="p">)</span></div>
<div class="viewcode-block" id="PersistTask.task_run"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.task_run">[docs]</a> <span class="k">def</span> <span class="nf">task_run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Stage any outstanding changes.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">counter</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">content_id</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">counter</span><span class="o">.</span><span class="n">most_common</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">MAX_SAVE</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="n">content_id</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span></div>
<div class="viewcode-block" id="PersistTask.commit"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.commit">[docs]</a> <span class="k">def</span> <span class="nf">commit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="o">=</span><span class="s1">&#39;auto-commit&#39;</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Commit.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">repo</span><span class="o">.</span><span class="n">do_commit</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">committer</span><span class="o">=</span><span class="n">core</span><span class="o">.</span><span class="n">COMMITTER</span><span class="p">)</span></div>
<div class="viewcode-block" id="PersistTask.scan"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.PersistTask.scan">[docs]</a> <span class="k">def</span> <span class="nf">scan</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a sorted list of all the files in the home dir.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">([</span>
<span class="n">fn</span>
<span class="k">for</span> <span class="n">fn</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">home</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">home</span><span class="p">,</span> <span class="n">fn</span><span class="p">))</span>
<span class="p">])</span></div></div>
<div class="viewcode-block" id="check_filename"><a class="viewcode-back" href="../../../persist_task.html#joy.vui.persist_task.check_filename">[docs]</a><span class="k">def</span> <span class="nf">check_filename</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Sanity checks for filename.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="c1"># TODO: improve this...</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">64</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;bad name </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,))</span>
<span class="n">left</span><span class="p">,</span> <span class="n">dot</span><span class="p">,</span> <span class="n">right</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">partition</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">left</span><span class="o">.</span><span class="n">isalnum</span><span class="p">()</span> <span class="ow">or</span> <span class="n">dot</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">right</span><span class="o">.</span><span class="n">isalnum</span><span class="p">():</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;bad name </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,))</span></div>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
<span class="n">JOY_HOME</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s1">&#39;~/.thun&#39;</span><span class="p">)</span>
<span class="n">pt</span> <span class="o">=</span> <span class="n">PersistTask</span><span class="p">(</span><span class="n">JOY_HOME</span><span class="p">)</span>
<span class="n">content_id</span><span class="p">,</span> <span class="n">thing</span> <span class="o">=</span> <span class="n">pt</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">&#39;stack.pickle&#39;</span><span class="p">)</span>
<span class="n">pt</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="n">content_id</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">pt</span><span class="o">.</span><span class="n">counter</span>
<span class="n">mm</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">ModifyMessage</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">content_id</span><span class="o">=</span><span class="n">content_id</span><span class="p">)</span>
<span class="n">pt</span><span class="o">.</span><span class="n">handle</span><span class="p">(</span><span class="n">mm</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">pt</span><span class="o">.</span><span class="n">counter</span>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,175 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.vui.stack_viewer &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.vui.stack_viewer</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="c1">#</span>
<span class="c1"># Copyright © 2019 Simon Forman</span>
<span class="c1">#</span>
<span class="c1"># This file is part of Thun</span>
<span class="c1">#</span>
<span class="c1"># Thun is free software: you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># Thun is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with Thun. If not see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">Stack Viewer</span>
<span class="sd">=================</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">iter_stack</span>
<span class="kn">from</span> <span class="nn">joy.vui</span> <span class="k">import</span> <span class="n">core</span><span class="p">,</span> <span class="n">text_viewer</span>
<span class="n">MAX_WIDTH</span> <span class="o">=</span> <span class="mi">64</span>
<div class="viewcode-block" id="fsi"><a class="viewcode-back" href="../../../stack_viewer.html#joy.vui.stack_viewer.fsi">[docs]</a><span class="k">def</span> <span class="nf">fsi</span><span class="p">(</span><span class="n">item</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Format Stack Item&#39;&#39;&#39;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="n">res</span> <span class="o">=</span> <span class="s1">&#39;[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="n">expression_to_string</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">res</span> <span class="o">=</span> <span class="s1">&#39;&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">item</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">unicode</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
<span class="n">res</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">res</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">MAX_WIDTH</span><span class="p">:</span>
<span class="k">return</span> <span class="n">res</span><span class="p">[:</span><span class="n">MAX_WIDTH</span> <span class="o">-</span> <span class="mi">3</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;...&#39;</span>
<span class="k">return</span> <span class="n">res</span></div>
<div class="viewcode-block" id="StackViewer"><a class="viewcode-back" href="../../../stack_viewer.html#joy.vui.stack_viewer.StackViewer">[docs]</a><span class="k">class</span> <span class="nc">StackViewer</span><span class="p">(</span><span class="n">text_viewer</span><span class="o">.</span><span class="n">TextViewer</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">StackViewer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">surface</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">content_id</span> <span class="o">=</span> <span class="s1">&#39;stack viewer&#39;</span>
<span class="k">def</span> <span class="nf">_attach</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">om</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">OpenMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;stack.pickle&#39;</span><span class="p">)</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">om</span><span class="p">)</span>
<span class="k">if</span> <span class="n">om</span><span class="o">.</span><span class="n">status</span> <span class="o">!=</span> <span class="n">core</span><span class="o">.</span><span class="n">SUCCESS</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">&#39;stack unavailable&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span> <span class="o">=</span> <span class="n">om</span><span class="o">.</span><span class="n">thing</span>
<span class="k">def</span> <span class="nf">_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[:]</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">fsi</span><span class="p">,</span> <span class="n">iter_stack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="ow">or</span> <span class="p">[</span><span class="s1">&#39;&#39;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">focus</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_attach</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="nb">super</span><span class="p">(</span><span class="n">StackViewer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">focus</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">core</span><span class="o">.</span><span class="n">ModifyMessage</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">subject</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack_holder</span>
<span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_update</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,799 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.vui.text_viewer &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.vui.text_viewer</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="c1">#</span>
<span class="c1"># Copyright © 2019 Simon Forman</span>
<span class="c1">#</span>
<span class="c1"># This file is part of Thun</span>
<span class="c1">#</span>
<span class="c1"># Thun is free software: you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># Thun is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with Thun. If not see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">Text Viewer</span>
<span class="sd">=================</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">import</span> <span class="nn">string</span>
<span class="kn">import</span> <span class="nn">pygame</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">expression_to_string</span>
<span class="kn">from</span> <span class="nn">joy.vui.core</span> <span class="k">import</span> <span class="p">(</span>
<span class="n">ARROW_KEYS</span><span class="p">,</span>
<span class="n">BACKGROUND</span> <span class="k">as</span> <span class="n">BG</span><span class="p">,</span>
<span class="n">FOREGROUND</span> <span class="k">as</span> <span class="n">FG</span><span class="p">,</span>
<span class="n">CommandMessage</span><span class="p">,</span>
<span class="n">ModifyMessage</span><span class="p">,</span>
<span class="n">OpenMessage</span><span class="p">,</span>
<span class="n">SUCCESS</span><span class="p">,</span>
<span class="n">push</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">joy.vui</span> <span class="k">import</span> <span class="n">viewer</span><span class="p">,</span> <span class="n">font_data</span>
<span class="c1">#reload(viewer)</span>
<span class="n">MenuViewer</span> <span class="o">=</span> <span class="n">viewer</span><span class="o">.</span><span class="n">MenuViewer</span>
<span class="n">SELECTION_COLOR</span> <span class="o">=</span> <span class="mi">235</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">32</span>
<span class="n">SELECTION_KEYS</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F1</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F2</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F3</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F4</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">STACK_CHATTER_KEYS</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F5</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F6</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F7</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">K_F8</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">def</span> <span class="nf">_is_command</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">word</span><span class="p">):</span>
<span class="k">return</span> <span class="n">display</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">word</span><span class="p">)</span> <span class="ow">or</span> <span class="n">word</span><span class="o">.</span><span class="n">isdigit</span><span class="p">()</span> <span class="ow">or</span> <span class="nb">all</span><span class="p">(</span>
<span class="ow">not</span> <span class="n">s</span> <span class="ow">or</span> <span class="n">s</span><span class="o">.</span><span class="n">isdigit</span><span class="p">()</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">word</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">)</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">word</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="k">def</span> <span class="nf">format_stack_item</span><span class="p">(</span><span class="n">content</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">&#39;[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="n">expression_to_string</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Font</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="n">IMAGE</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">image</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">font_data</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="s1">&#39;Iosevka12.BMP&#39;</span><span class="p">)</span>
<span class="n">LOOKUP</span> <span class="o">=</span> <span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">ascii_letters</span> <span class="o">+</span>
<span class="n">string</span><span class="o">.</span><span class="n">digits</span> <span class="o">+</span>
<span class="sd">&#39;&#39;&#39;@#$&amp;_~|`&#39;&quot;%^=-+*/\\&lt;&gt;[]{}(),.;:!?&#39;&#39;&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">char_w</span><span class="o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n">char_h</span><span class="o">=</span><span class="mi">19</span><span class="p">,</span> <span class="n">line_h</span><span class="o">=</span><span class="mi">19</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char_w</span> <span class="o">=</span> <span class="n">char_w</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char_h</span> <span class="o">=</span> <span class="n">char_h</span>
<span class="bp">self</span><span class="o">.</span><span class="n">line_h</span> <span class="o">=</span> <span class="n">line_h</span>
<span class="k">def</span> <span class="nf">size</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">char_w</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">text</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">line_h</span>
<span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
<span class="n">surface</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">Surface</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">text</span><span class="p">))</span>
<span class="n">surface</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span><span class="n">BG</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">ch</span> <span class="ow">in</span> <span class="n">text</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">ch</span><span class="o">.</span><span class="n">isspace</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">LOOKUP</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">ch</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="c1"># render a lil box...</span>
<span class="n">r</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">line_h</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">-</span> <span class="mi">3</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char_w</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">line_h</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">rect</span><span class="p">(</span><span class="n">surface</span><span class="p">,</span> <span class="n">FG</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">iy</span><span class="p">,</span> <span class="n">ix</span> <span class="o">=</span> <span class="nb">divmod</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="mi">26</span><span class="p">)</span>
<span class="n">ix</span> <span class="o">*=</span> <span class="bp">self</span><span class="o">.</span><span class="n">char_w</span>
<span class="n">iy</span> <span class="o">*=</span> <span class="bp">self</span><span class="o">.</span><span class="n">char_h</span>
<span class="n">area</span> <span class="o">=</span> <span class="n">ix</span><span class="p">,</span> <span class="n">iy</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">char_h</span>
<span class="n">surface</span><span class="o">.</span><span class="n">blit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">IMAGE</span><span class="p">,</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">area</span><span class="p">)</span>
<span class="n">x</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">char_w</span>
<span class="k">return</span> <span class="n">surface</span>
<span class="k">def</span> <span class="nf">__contains__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">char</span><span class="p">):</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">char</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
<span class="k">return</span> <span class="n">char</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">LOOKUP</span>
<span class="n">FONT</span> <span class="o">=</span> <span class="n">Font</span><span class="p">()</span>
<div class="viewcode-block" id="TextViewer"><a class="viewcode-back" href="../../../text_viewer.html#joy.vui.text_viewer.TextViewer">[docs]</a><span class="k">class</span> <span class="nc">TextViewer</span><span class="p">(</span><span class="n">MenuViewer</span><span class="p">):</span>
<span class="n">MINIMUM_HEIGHT</span> <span class="o">=</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span> <span class="o">+</span> <span class="mi">3</span>
<span class="n">CLOSE_TEXT</span> <span class="o">=</span> <span class="n">FONT</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="s1">&#39;close&#39;</span><span class="p">)</span>
<span class="n">GROW_TEXT</span> <span class="o">=</span> <span class="n">FONT</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="s1">&#39;grow&#39;</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Cursor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">viewer</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">v</span> <span class="o">=</span> <span class="n">viewer</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mem</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">Surface</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">can_fade</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">def</span> <span class="nf">set_to</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mem</span><span class="o">.</span><span class="n">blit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">body_surface</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">r</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">body_surface</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span><span class="n">FG</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">can_fade</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">fade</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">can_fade</span><span class="p">:</span>
<span class="n">dest</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">screen_y</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">body_surface</span><span class="o">.</span><span class="n">blit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mem</span><span class="p">,</span> <span class="n">dest</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">can_fade</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">def</span> <span class="nf">screen_y</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">row</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">row</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span>
<span class="k">return</span> <span class="p">(</span><span class="n">row</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">at_line</span><span class="p">)</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span>
<span class="k">def</span> <span class="nf">up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_mod</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">]))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_mod</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">]))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_check_scroll</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">left</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_mod</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_check_scroll</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">right</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_mod</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">]):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_check_scroll</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_check_scroll</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">at_line</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">scroll_down</span><span class="p">()</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">at_line</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">h_in_lines</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">scroll_up</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">Cursor</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">MenuViewer</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;&#39;</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">content_id</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_line</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">bg</span> <span class="o">=</span> <span class="n">BG</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">command_rect</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">resurface</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="n">MenuViewer</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">)</span>
<span class="n">w</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">CLOSE_TEXT</span><span class="o">.</span><span class="n">get_size</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">close_rect</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">rect</span><span class="o">.</span><span class="n">Rect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">-</span> <span class="n">w</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
<span class="n">w</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">GROW_TEXT</span><span class="o">.</span><span class="n">get_size</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">grow_rect</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">rect</span><span class="o">.</span><span class="n">Rect</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body_surface</span> <span class="o">=</span> <span class="n">surface</span><span class="o">.</span><span class="n">subsurface</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">line_w</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">w</span> <span class="o">/</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span> <span class="o">+</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">h_in_lines</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">h</span> <span class="o">/</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span> <span class="o">-</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command_rect</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">super</span><span class="p">(</span><span class="n">TextViewer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">handle</span><span class="p">(</span><span class="n">message</span><span class="p">):</span>
<span class="k">return</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">ModifyMessage</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">subject</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span>
<span class="p">):</span>
<span class="c1"># TODO: check self.at_line</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span>
<span class="c1"># Drawing</span>
<span class="k">def</span> <span class="nf">draw_menu</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1">#MenuViewer.draw_menu(self)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">blit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">GROW_TEXT</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">blit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">CLOSE_TEXT</span><span class="p">,</span>
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">close_rect</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">content_id</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">blit</span><span class="p">(</span><span class="n">FONT</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="s1">&#39;| &#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">content_id</span><span class="p">),</span>
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">grow_rect</span><span class="o">.</span><span class="n">w</span> <span class="o">+</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span> <span class="o">+</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span> <span class="c1"># light grey background</span>
<span class="p">(</span><span class="mi">196</span><span class="p">,</span> <span class="mi">196</span><span class="p">,</span> <span class="mi">196</span><span class="p">),</span>
<span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span><span class="p">),</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">BLEND_MULT</span>
<span class="p">)</span>
<span class="k">def</span> <span class="nf">draw_body</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">MenuViewer</span><span class="o">.</span><span class="n">draw_body</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">ys</span> <span class="o">=</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">height</span><span class="p">,</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span><span class="p">)</span>
<span class="n">ls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">at_line</span><span class="p">:</span><span class="bp">self</span><span class="o">.</span><span class="n">at_line</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">h_in_lines</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span>
<span class="k">for</span> <span class="n">y</span><span class="p">,</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">ys</span><span class="p">,</span> <span class="n">ls</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_line</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">draw_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
<span class="n">surface</span> <span class="o">=</span> <span class="n">FONT</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">line</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">line_w</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body_surface</span><span class="o">.</span><span class="n">blit</span><span class="p">(</span><span class="n">surface</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_redraw_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">row</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span> <span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">row</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span> <span class="n">line</span> <span class="o">=</span> <span class="s1">&#39; &#39;</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">line_w</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">line_w</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span> <span class="n">line</span> <span class="o">=</span> <span class="n">line</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">*</span> <span class="n">n</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(</span><span class="n">row</span><span class="p">),</span> <span class="n">line</span><span class="p">)</span>
<span class="c1"># General Functionality</span>
<span class="k">def</span> <span class="nf">focus</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">v</span> <span class="o">=</span> <span class="bp">self</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">unfocus</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">scroll_up</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_line</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_fade_command</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_deselect</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_line</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body_surface</span><span class="o">.</span><span class="n">scroll</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span><span class="p">)</span>
<span class="n">row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">h_in_lines</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_line</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_redraw_line</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_redraw_line</span><span class="p">(</span><span class="n">row</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">scroll_down</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_line</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_fade_command</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_deselect</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_line</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body_surface</span><span class="o">.</span><span class="n">scroll</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_redraw_line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">at_line</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">command_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">command_rect</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">command_rect</span><span class="o">.</span><span class="n">collidepoint</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_fade_command</span><span class="p">()</span>
<span class="n">line</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">_row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="n">word_start</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">rfind</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">word_end</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span>
<span class="k">if</span> <span class="n">word_end</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span> <span class="n">word_end</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">word</span> <span class="o">=</span> <span class="n">line</span><span class="p">[</span><span class="n">word_start</span><span class="p">:</span><span class="n">word_end</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_is_command</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">word</span><span class="p">):</span>
<span class="k">return</span>
<span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">command_rect</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">Rect</span><span class="p">(</span>
<span class="n">word_start</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span> <span class="c1"># x</span>
<span class="n">y</span> <span class="o">/</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span><span class="p">,</span> <span class="c1"># y</span>
<span class="nb">len</span><span class="p">(</span><span class="n">word</span><span class="p">)</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span> <span class="c1"># w</span>
<span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span> <span class="c1"># h</span>
<span class="p">)</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">body_surface</span><span class="p">,</span> <span class="n">FG</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">bottomleft</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">bottomright</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">word</span>
<span class="k">def</span> <span class="nf">command_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_fade_command</span><span class="p">()</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">CommandMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">command</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_fade_command</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">r</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">command_rect</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">command_rect</span><span class="p">,</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">r</span><span class="p">:</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">body_surface</span><span class="p">,</span> <span class="n">BG</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">bottomleft</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">bottomright</span><span class="p">)</span>
<div class="viewcode-block" id="TextViewer.at"><a class="viewcode-back" href="../../../text_viewer.html#joy.vui.text_viewer.TextViewer.at">[docs]</a> <span class="k">def</span> <span class="nf">at</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Given screen coordinates return the line, row, and column of the</span>
<span class="sd"> character there.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_line</span> <span class="o">+</span> <span class="n">y</span> <span class="o">/</span> <span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">row</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="n">row</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">row</span><span class="p">]</span>
<span class="n">column</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">column</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">x</span> <span class="o">/</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">))</span>
<span class="k">return</span> <span class="n">line</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">row</span></div>
<span class="c1"># Event Processing</span>
<span class="k">def</span> <span class="nf">body_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">_line</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">set_to</span><span class="p">(</span><span class="n">column</span><span class="p">,</span> <span class="n">row</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">if</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_SHIFT</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">get_mods</span><span class="p">():</span>
<span class="bp">self</span><span class="o">.</span><span class="n">scroll_up</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">scroll_down</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command_down</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">4</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">scroll_down</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">5</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">scroll_up</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">menu_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">MenuViewer</span><span class="o">.</span><span class="n">menu_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">mouse_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">MenuViewer</span><span class="o">.</span><span class="n">mouse_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">elif</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">3</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">collidepoint</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command_up</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">mouse_motion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">rel_x</span><span class="p">,</span> <span class="n">rel_y</span><span class="p">,</span> <span class="n">button0</span><span class="p">,</span> <span class="n">button1</span><span class="p">,</span> <span class="n">button2</span><span class="p">):</span>
<span class="k">if</span> <span class="n">MenuViewer</span><span class="o">.</span><span class="n">mouse_motion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">rel_x</span><span class="p">,</span> <span class="n">rel_y</span><span class="p">,</span>
<span class="n">button0</span><span class="p">,</span> <span class="n">button1</span><span class="p">,</span> <span class="n">button2</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">if</span> <span class="p">(</span><span class="n">button0</span>
<span class="ow">and</span> <span class="n">display</span><span class="o">.</span><span class="n">focused_viewer</span> <span class="ow">is</span> <span class="bp">self</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">collidepoint</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="p">):</span>
<span class="n">bx</span><span class="p">,</span> <span class="n">by</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">topleft</span>
<span class="n">_line</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="n">bx</span><span class="p">,</span> <span class="n">y</span> <span class="o">-</span> <span class="n">by</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">set_to</span><span class="p">(</span><span class="n">column</span><span class="p">,</span> <span class="n">row</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">button2</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">collidepoint</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="n">bx</span><span class="p">,</span> <span class="n">by</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">topleft</span>
<span class="bp">self</span><span class="o">.</span><span class="n">command_down</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">x</span> <span class="o">-</span> <span class="n">bx</span><span class="p">,</span> <span class="n">y</span> <span class="o">-</span> <span class="n">by</span><span class="p">)</span>
<div class="viewcode-block" id="TextViewer.close"><a class="viewcode-back" href="../../../text_viewer.html#joy.vui.text_viewer.TextViewer.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="kc">None</span></div>
<span class="k">def</span> <span class="nf">key_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">uch</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">SELECTION_KEYS</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_selection_key</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">STACK_CHATTER_KEYS</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_stack_chatter_key</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ARROW_KEYS</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_arrow_key</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">line</span><span class="p">,</span> <span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span>
<span class="n">modified</span> <span class="o">=</span> <span class="p">()</span>
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_RETURN</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_return_key</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
<span class="n">modified</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_BACKSPACE</span><span class="p">:</span>
<span class="n">modified</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_backspace_key</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_DELETE</span><span class="p">:</span>
<span class="n">modified</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_delete_key</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_INSERT</span><span class="p">:</span>
<span class="n">modified</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_insert_key</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">uch</span> <span class="ow">and</span> <span class="n">uch</span> <span class="ow">in</span> <span class="n">FONT</span> <span class="ow">or</span> <span class="n">uch</span> <span class="o">==</span> <span class="s1">&#39; &#39;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_printable_key</span><span class="p">(</span><span class="n">uch</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
<span class="n">modified</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="s1">&#39;</span><span class="si">%r</span><span class="s1"> </span><span class="si">%i</span><span class="s1"> </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">uch</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="nb">bin</span><span class="p">(</span><span class="n">mod</span><span class="p">))</span>
<span class="k">if</span> <span class="n">modified</span><span class="p">:</span>
<span class="c1"># The selection is fragile.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_deselect</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">ModifyMessage</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">,</span> <span class="n">content_id</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">content_id</span><span class="p">)</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_stack_chatter_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_F5</span><span class="p">:</span>
<span class="k">if</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_SHIFT</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="s1">&#39;roll&lt;&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="s1">&#39;swap&#39;</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_F6</span><span class="p">:</span>
<span class="k">if</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_SHIFT</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="s1">&#39;roll&gt;&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="s1">&#39;dup&#39;</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_F7</span><span class="p">:</span>
<span class="k">if</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_SHIFT</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="s1">&#39;tuck&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="s1">&#39;over&#39;</span>
<span class="c1">## elif key == pygame.K_F8:</span>
<span class="c1">## if mod &amp; pygame.KMOD_SHIFT:</span>
<span class="c1">## command = &#39;&#39;</span>
<span class="c1">## else:</span>
<span class="c1">## command = &#39;&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">CommandMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">command</span><span class="p">))</span>
<span class="c1"># Selection Handling</span>
<span class="k">def</span> <span class="nf">_selection_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_deselect</span><span class="p">()</span>
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_F1</span><span class="p">:</span> <span class="c1"># set sel start</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_update_selection</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_F2</span><span class="p">:</span> <span class="c1"># set sel end</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_update_selection</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_F3</span><span class="p">:</span> <span class="c1"># copy</span>
<span class="k">if</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_SHIFT</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_parse_selection</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_copy_selection</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_update_selection</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_F4</span><span class="p">:</span> <span class="c1"># cut or delete</span>
<span class="k">if</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_SHIFT</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_delete_selection</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cut_selection</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_deselect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_selection</span><span class="p">():</span>
<span class="n">srow</span><span class="p">,</span> <span class="n">erow</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="c1"># Just erase the whole selection.</span>
<span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">min</span><span class="p">(</span><span class="n">srow</span><span class="p">,</span> <span class="n">erow</span><span class="p">),</span> <span class="nb">max</span><span class="p">(</span><span class="n">srow</span><span class="p">,</span> <span class="n">erow</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_redraw_line</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_copy_selection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="k">if</span> <span class="n">push</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_selection</span><span class="p">(),</span> <span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">)</span> <span class="o">==</span> <span class="n">SUCCESS</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="c1">## om = OpenMessage(self, &#39;stack.pickle&#39;)</span>
<span class="c1">## display.broadcast(om)</span>
<span class="c1">## if om.status == SUCCESS:</span>
<span class="c1">## selection = self._get_selection()</span>
<span class="c1">## om.thing[0] = selection, om.thing[0]</span>
<span class="c1">## display.broadcast(ModifyMessage(</span>
<span class="c1">## self, om.thing, content_id=om.content_id))</span>
<span class="k">def</span> <span class="nf">_parse_selection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_selection</span><span class="p">():</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_copy_selection</span><span class="p">(</span><span class="n">display</span><span class="p">):</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">CommandMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;parse&#39;</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_cut_selection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_selection</span><span class="p">():</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_copy_selection</span><span class="p">(</span><span class="n">display</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_delete_selection</span><span class="p">(</span><span class="n">display</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_delete_selection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_selection</span><span class="p">():</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="n">srow</span><span class="p">,</span> <span class="n">scolumn</span><span class="p">,</span> <span class="n">erow</span><span class="p">,</span> <span class="n">ecolumn</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_selection_coords</span><span class="p">()</span>
<span class="k">if</span> <span class="n">srow</span> <span class="o">==</span> <span class="n">erow</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">srow</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">srow</span><span class="p">]</span> <span class="o">=</span> <span class="n">line</span><span class="p">[:</span><span class="n">scolumn</span><span class="p">]</span> <span class="o">+</span> <span class="n">line</span><span class="p">[</span><span class="n">ecolumn</span><span class="p">:]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">left</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">srow</span><span class="p">][:</span><span class="n">scolumn</span><span class="p">]</span>
<span class="n">right</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">erow</span><span class="p">][</span><span class="n">ecolumn</span><span class="p">:]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">srow</span><span class="p">:</span><span class="n">erow</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">set_to</span><span class="p">(</span><span class="n">srow</span><span class="p">,</span> <span class="n">scolumn</span><span class="p">)</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">ModifyMessage</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">,</span> <span class="n">content_id</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">content_id</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_has_selection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_get_selection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Return the current selection if any as a single string.&#39;&#39;&#39;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_selection</span><span class="p">():</span>
<span class="k">return</span> <span class="s1">&#39;&#39;</span>
<span class="n">srow</span><span class="p">,</span> <span class="n">scolumn</span><span class="p">,</span> <span class="n">erow</span><span class="p">,</span> <span class="n">ecolumn</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_selection_coords</span><span class="p">()</span>
<span class="k">if</span> <span class="n">srow</span> <span class="o">==</span> <span class="n">erow</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">srow</span><span class="p">][</span><span class="n">scolumn</span><span class="p">:</span><span class="n">ecolumn</span><span class="p">])</span>
<span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">assert</span> <span class="n">srow</span> <span class="o">&lt;</span> <span class="n">erow</span>
<span class="k">while</span> <span class="n">srow</span> <span class="o">&lt;=</span> <span class="n">erow</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">srow</span><span class="p">]</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">ecolumn</span> <span class="k">if</span> <span class="n">srow</span> <span class="o">==</span> <span class="n">erow</span> <span class="k">else</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="n">scolumn</span><span class="p">:</span><span class="n">e</span><span class="p">])</span>
<span class="n">scolumn</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">srow</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_selection_coords</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="p">(</span><span class="n">srow</span><span class="p">,</span> <span class="n">scolumn</span><span class="p">),</span> <span class="p">(</span><span class="n">erow</span><span class="p">,</span> <span class="n">ecolumn</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span>
<span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span><span class="p">),</span>
<span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">srow</span><span class="p">,</span> <span class="n">scolumn</span><span class="p">,</span> <span class="n">erow</span><span class="p">,</span> <span class="n">ecolumn</span>
<span class="k">def</span> <span class="nf">_update_selection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_start</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sel_end</span><span class="p">:</span>
<span class="k">for</span> <span class="n">rect</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_iter_selection_rectangles</span><span class="p">():</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body_surface</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span>
<span class="n">SELECTION_COLOR</span><span class="p">,</span>
<span class="n">rect</span><span class="p">,</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">BLEND_RGBA_MULT</span>
<span class="p">)</span>
<span class="k">def</span> <span class="nf">_iter_selection_rectangles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">):</span>
<span class="n">srow</span><span class="p">,</span> <span class="n">scolumn</span><span class="p">,</span> <span class="n">erow</span><span class="p">,</span> <span class="n">ecolumn</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_selection_coords</span><span class="p">()</span>
<span class="k">if</span> <span class="n">srow</span> <span class="o">==</span> <span class="n">erow</span><span class="p">:</span>
<span class="k">yield</span> <span class="p">(</span>
<span class="n">scolumn</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(</span><span class="n">srow</span><span class="p">),</span>
<span class="p">(</span><span class="n">ecolumn</span> <span class="o">-</span> <span class="n">scolumn</span><span class="p">)</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span>
<span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="n">lines</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">srow</span><span class="p">:</span><span class="n">erow</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<span class="n">first_line</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">yield</span> <span class="p">(</span>
<span class="n">scolumn</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(</span><span class="n">srow</span><span class="p">),</span>
<span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">first_line</span><span class="p">)</span> <span class="o">-</span> <span class="n">scolumn</span><span class="p">)</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span>
<span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span>
<span class="p">)</span>
<span class="k">yield</span> <span class="p">(</span>
<span class="mi">0</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(</span><span class="n">erow</span><span class="p">),</span>
<span class="n">ecolumn</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span>
<span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span>
<span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
<span class="n">srow</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">yield</span> <span class="p">(</span>
<span class="mi">0</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(</span><span class="n">srow</span><span class="p">),</span>
<span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="o">*</span> <span class="n">FONT</span><span class="o">.</span><span class="n">char_w</span><span class="p">,</span>
<span class="n">FONT</span><span class="o">.</span><span class="n">line_h</span>
<span class="p">)</span>
<span class="c1"># Key Handlers</span>
<span class="k">def</span> <span class="nf">_printable_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uch</span><span class="p">,</span> <span class="n">_mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">uch</span> <span class="o">+</span> <span class="n">line</span><span class="p">[</span><span class="n">i</span><span class="p">:]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">line</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(),</span> <span class="n">line</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_backspace_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="n">res</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">i</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="p">[:</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">line</span><span class="p">[</span><span class="n">i</span><span class="p">:]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">line</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(),</span> <span class="n">line</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="n">res</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">:</span>
<span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span>
<span class="n">left</span><span class="p">,</span> <span class="n">right</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">y</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">y</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">left</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="n">res</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">return</span> <span class="n">res</span>
<span class="k">def</span> <span class="nf">_delete_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="n">res</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">):</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">line</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">line</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">screen_y</span><span class="p">(),</span> <span class="n">line</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="n">res</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span>
<span class="n">left</span><span class="p">,</span> <span class="n">right</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="n">res</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">return</span> <span class="n">res</span>
<span class="k">def</span> <span class="nf">_arrow_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_UP</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">up</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_DOWN</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">down</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_LEFT</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">left</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_RIGHT</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">right</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_return_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_mod</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="c1"># Ignore the mods for now.</span>
<span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">n</span><span class="p">:</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="p">[:</span><span class="n">i</span><span class="p">],</span> <span class="n">line</span><span class="p">[</span><span class="n">i</span><span class="p">:]]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_line</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">h_in_lines</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">scroll_up</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_insert_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">_line</span><span class="p">,</span> <span class="n">_i</span><span class="p">):</span>
<span class="n">om</span> <span class="o">=</span> <span class="n">OpenMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;stack.pickle&#39;</span><span class="p">)</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">om</span><span class="p">)</span>
<span class="k">if</span> <span class="n">om</span><span class="o">.</span><span class="n">status</span> <span class="o">!=</span> <span class="n">SUCCESS</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">om</span><span class="o">.</span><span class="n">thing</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="n">stack</span><span class="p">:</span>
<span class="n">content</span> <span class="o">=</span> <span class="n">format_stack_item</span><span class="p">(</span><span class="n">stack</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">content</span><span class="p">):</span>
<span class="k">if</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_SHIFT</span><span class="p">:</span>
<span class="n">display</span><span class="o">.</span><span class="n">broadcast</span><span class="p">(</span><span class="n">CommandMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;pop&#39;</span><span class="p">))</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">insert</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">basestring</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="k">if</span> <span class="n">content</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="n">row</span><span class="p">,</span> <span class="n">column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span>
<span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">row</span><span class="p">]</span>
<span class="n">lines</span> <span class="o">=</span> <span class="p">(</span><span class="n">line</span><span class="p">[:</span><span class="n">column</span><span class="p">]</span> <span class="o">+</span> <span class="n">content</span> <span class="o">+</span> <span class="n">line</span><span class="p">[</span><span class="n">column</span><span class="p">:])</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="n">row</span><span class="p">:</span><span class="n">row</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">lines</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">row</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="o">+</span> <span class="n">column</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">append</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">fade</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">cursor</span><span class="o">.</span><span class="n">y</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">content</span><span class="p">)</span></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,345 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.vui.viewer &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.vui.viewer</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="c1">#</span>
<span class="c1"># Copyright © 2019 Simon Forman</span>
<span class="c1">#</span>
<span class="c1"># This file is part of joy.py</span>
<span class="c1">#</span>
<span class="c1"># joy.py is free software: you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># joy.py is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with joy.py. If not see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">Viewer</span>
<span class="sd">=================</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">import</span> <span class="nn">pygame</span>
<span class="kn">from</span> <span class="nn">joy.vui.core</span> <span class="k">import</span> <span class="n">BACKGROUND</span><span class="p">,</span> <span class="n">FOREGROUND</span>
<div class="viewcode-block" id="Viewer"><a class="viewcode-back" href="../../../viewer.html#joy.vui.viewer.Viewer">[docs]</a><span class="k">class</span> <span class="nc">Viewer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Base Viewer class</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">MINIMUM_HEIGHT</span> <span class="o">=</span> <span class="mi">11</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="n">surface</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">last_touch</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">resurface</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">=</span> <span class="n">surface</span><span class="o">.</span><span class="n">get_width</span><span class="p">(),</span> <span class="n">surface</span><span class="o">.</span><span class="n">get_height</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span> <span class="o">=</span> <span class="n">surface</span>
<div class="viewcode-block" id="Viewer.split"><a class="viewcode-back" href="../../../viewer.html#joy.vui.viewer.Viewer.split">[docs]</a> <span class="k">def</span> <span class="nf">split</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Split the viewer at the y coordinate (which is relative to the</span>
<span class="sd"> viewer&#39;s surface and must be inside it somewhere) and return the</span>
<span class="sd"> remaining height. The upper part of the viewer remains (and gets</span>
<span class="sd"> redrawn on a new surface) and the lower space is now available</span>
<span class="sd"> for e.g. a new viewer.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">assert</span> <span class="n">y</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span>
<span class="n">new_viewer_h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">-</span> <span class="n">y</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">subsurface</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span><span class="p">,</span> <span class="n">y</span><span class="p">)))</span>
<span class="k">if</span> <span class="n">y</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_touch</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_touch</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="k">return</span> <span class="n">new_viewer_h</span></div>
<span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="k">assert</span> <span class="bp">self</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">sender</span>
<span class="k">pass</span>
<div class="viewcode-block" id="Viewer.draw"><a class="viewcode-back" href="../../../viewer.html#joy.vui.viewer.Viewer.draw">[docs]</a> <span class="k">def</span> <span class="nf">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Draw the viewer onto its surface.&#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span><span class="n">BACKGROUND</span><span class="p">)</span>
<span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">-</span> <span class="mi">1</span>
<span class="c1"># Right-hand side.</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="p">,</span> <span class="n">FOREGROUND</span><span class="p">,</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">h</span><span class="p">))</span>
<span class="c1"># Between header and body.</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="p">,</span> <span class="n">FOREGROUND</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">y</span><span class="p">),</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>
<span class="c1"># Bottom.</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">line</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="p">,</span> <span class="n">FOREGROUND</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">h</span><span class="p">),</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">h</span><span class="p">))</span></div>
<div class="viewcode-block" id="Viewer.close"><a class="viewcode-back" href="../../../viewer.html#joy.vui.viewer.Viewer.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Close the viewer and release any resources, etc...&#39;&#39;&#39;</span></div>
<span class="k">def</span> <span class="nf">focus</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">unfocus</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">pass</span>
<span class="c1"># Event handling.</span>
<span class="k">def</span> <span class="nf">mouse_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">last_touch</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">mouse_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">mouse_motion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">dy</span><span class="p">,</span> <span class="n">button0</span><span class="p">,</span> <span class="n">button1</span><span class="p">,</span> <span class="n">button2</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">key_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_q</span> <span class="ow">and</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_CTRL</span><span class="p">:</span> <span class="c1"># Ctrl-q</span>
<span class="n">display</span><span class="o">.</span><span class="n">close_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">pygame</span><span class="o">.</span><span class="n">K_g</span> <span class="ow">and</span> <span class="n">mod</span> <span class="o">&amp;</span> <span class="n">pygame</span><span class="o">.</span><span class="n">KMOD_CTRL</span><span class="p">:</span> <span class="c1"># Ctrl-g</span>
<span class="n">display</span><span class="o">.</span><span class="n">grow_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">key_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">uch</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="MenuViewer"><a class="viewcode-back" href="../../../viewer.html#joy.vui.viewer.MenuViewer">[docs]</a><span class="k">class</span> <span class="nc">MenuViewer</span><span class="p">(</span><span class="n">Viewer</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> MenuViewer class</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">MINIMUM_HEIGHT</span> <span class="o">=</span> <span class="mi">26</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="n">Viewer</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">bg</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">150</span><span class="p">,</span> <span class="mi">100</span>
<span class="k">def</span> <span class="nf">resurface</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="n">Viewer</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">)</span>
<span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span> <span class="o">-</span> <span class="mi">2</span>
<span class="bp">self</span><span class="o">.</span><span class="n">close_rect</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">rect</span><span class="o">.</span><span class="n">Rect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">-</span> <span class="n">n</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">grow_rect</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">rect</span><span class="o">.</span><span class="n">Rect</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span> <span class="o">=</span> <span class="n">pygame</span><span class="o">.</span><span class="n">rect</span><span class="o">.</span><span class="n">Rect</span><span class="p">(</span>
<span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span>
<div class="viewcode-block" id="MenuViewer.draw"><a class="viewcode-back" href="../../../viewer.html#joy.vui.viewer.MenuViewer.draw">[docs]</a> <span class="k">def</span> <span class="nf">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Draw the viewer onto its surface.&#39;&#39;&#39;</span>
<span class="n">Viewer</span><span class="o">.</span><span class="n">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">resizing</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_menu</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_body</span><span class="p">()</span></div>
<span class="k">def</span> <span class="nf">draw_menu</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># menu buttons</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">rect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="p">,</span> <span class="n">FOREGROUND</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">close_rect</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">rect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="p">,</span> <span class="n">FOREGROUND</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">grow_rect</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">draw_body</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bg</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">mouse_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="n">Viewer</span><span class="o">.</span><span class="n">mouse_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">)</span>
<span class="k">if</span> <span class="n">y</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">MINIMUM_HEIGHT</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">menu_click</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">bx</span><span class="p">,</span> <span class="n">by</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_rect</span><span class="o">.</span><span class="n">topleft</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body_click</span><span class="p">(</span><span class="n">display</span><span class="p">,</span> <span class="n">x</span> <span class="o">-</span> <span class="n">bx</span><span class="p">,</span> <span class="n">y</span> <span class="o">-</span> <span class="n">by</span><span class="p">,</span> <span class="n">button</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">body_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_an_a</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">menu_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">elif</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">close_rect</span><span class="o">.</span><span class="n">collidepoint</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="n">display</span><span class="o">.</span><span class="n">close_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">grow_rect</span><span class="o">.</span><span class="n">collidepoint</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="n">display</span><span class="o">.</span><span class="n">grow_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">mouse_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">button</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">resizing</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="n">display</span><span class="o">.</span><span class="n">done_resizing</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">mouse_motion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">rel_x</span><span class="p">,</span> <span class="n">rel_y</span><span class="p">,</span> <span class="n">button0</span><span class="p">,</span> <span class="n">button1</span><span class="p">,</span> <span class="n">button2</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="ow">and</span> <span class="n">button0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">display</span><span class="o">.</span><span class="n">change_viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rel_y</span><span class="p">,</span> <span class="n">relative</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resizing</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1">#self.draw_an_a(x, y)</span>
<span class="k">def</span> <span class="nf">key_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">if</span> <span class="n">Viewer</span><span class="o">.</span><span class="n">key_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">draw_an_a</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="c1"># Draw a crude letter A.</span>
<span class="n">lw</span><span class="p">,</span> <span class="n">lh</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">14</span>
<span class="k">try</span><span class="p">:</span> <span class="n">surface</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">surface</span><span class="o">.</span><span class="n">subsurface</span><span class="p">((</span><span class="n">x</span> <span class="o">-</span> <span class="n">lw</span><span class="p">,</span> <span class="n">y</span> <span class="o">-</span> <span class="n">lh</span><span class="p">,</span> <span class="n">lw</span><span class="p">,</span> <span class="n">lh</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">return</span>
<span class="n">draw_a</span><span class="p">(</span><span class="n">surface</span><span class="p">,</span> <span class="n">blend</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></div>
<div class="viewcode-block" id="SomeViewer"><a class="viewcode-back" href="../../../viewer.html#joy.vui.viewer.SomeViewer">[docs]</a><span class="k">class</span> <span class="nc">SomeViewer</span><span class="p">(</span><span class="n">MenuViewer</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="n">MenuViewer</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">resurface</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">):</span>
<span class="n">MenuViewer</span><span class="o">.</span><span class="n">resurface</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">surface</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">draw_menu</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">MenuViewer</span><span class="o">.</span><span class="n">draw_menu</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">draw_body</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">body_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">menu_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">MenuViewer</span><span class="o">.</span><span class="n">menu_click</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">mouse_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">if</span> <span class="n">MenuViewer</span><span class="o">.</span><span class="n">mouse_up</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">button</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">mouse_motion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">rel_x</span><span class="p">,</span> <span class="n">rel_y</span><span class="p">,</span> <span class="n">button0</span><span class="p">,</span> <span class="n">button1</span><span class="p">,</span> <span class="n">button2</span><span class="p">):</span>
<span class="k">if</span> <span class="n">MenuViewer</span><span class="o">.</span><span class="n">mouse_motion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">rel_x</span><span class="p">,</span> <span class="n">rel_y</span><span class="p">,</span>
<span class="n">button0</span><span class="p">,</span> <span class="n">button1</span><span class="p">,</span> <span class="n">button2</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">key_down</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">display</span><span class="p">,</span> <span class="n">uch</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">mod</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">print</span> <span class="nb">chr</span><span class="p">(</span><span class="n">key</span><span class="p">),</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">pass</span></div>
<span class="c1"># Note that Oberon book says that if you split at the exact top of a viewer</span>
<span class="c1"># it should close, and I think this implies the new viewer gets the old</span>
<span class="c1"># viewer&#39;s whole height. I haven&#39;t implemented that yet, so the edge-case</span>
<span class="c1"># in the code is broken by &quot;intent&quot; for now..</span>
<span class="k">def</span> <span class="nf">draw_a</span><span class="p">(</span><span class="n">surface</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="n">FOREGROUND</span><span class="p">,</span> <span class="n">blend</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="n">w</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="n">surface</span><span class="o">.</span><span class="n">get_width</span><span class="p">()</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="n">surface</span><span class="o">.</span><span class="n">get_height</span><span class="p">()</span> <span class="o">-</span> <span class="mi">2</span>
<span class="n">pygame</span><span class="o">.</span><span class="n">draw</span><span class="o">.</span><span class="n">aalines</span><span class="p">(</span><span class="n">surface</span><span class="p">,</span> <span class="n">color</span><span class="p">,</span> <span class="kc">False</span><span class="p">,</span> <span class="p">(</span>
<span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">h</span><span class="p">),</span> <span class="p">(</span><span class="n">w</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">h</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span>
<span class="p">),</span> <span class="n">blend</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.core
:members:

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.display
:members:

View File

@ -0,0 +1,160 @@
.. Joy VUI documentation master file, created by
sphinx-quickstart on Mon May 06 19:41:42 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Joy VUI's documentation!
===================================
A simple Graphical User Interface for the Joy programming language,
written using Pygame to bypass X11 et. al., modeled on the Oberon OS, and
intended to be just functional enough to support bootstrapping further Joy
development.
Screenshot
-----------------------------
.. image:: _static/Joy-VUI-screenshot.PNG
Quick Start
-----------------------------
If you have PyGame and Dulwich installed you should be able to start the
VUI with the following command:
::
python -m joy.vui
This will create a ``~/.thun`` directory in your home dir to store your
data.
How it works now.
-----------------------------
The VUI is more-or-less a crude text editor along with
a simple Joy runtime (interpreter, stack, and dictionary.) It auto-saves
any named files (in a versioned home directory) and you can write new Joy
primitives in Python and Joy definitions and immediately install and use
them, as well as recording them for reuse (after restarts.)
The only dependencies are Pygame and Dulwich (a Python Git library.)
When the main.py script starts it checks for an environment var "JOY_HOME"
which should point to a directory where you want the system to store the
files ("resources") it will edit and save, this directory defaults to
``~/.thun``. The first time you run it, it will create some default files
as content. Right click on see_resources to open a viewer with the list
of resources (files), copy a name to the stack and right click on
open_resource_at_good_location to open a viewer on that resource.
Right now the screen size defaults to windowed 1024x768, but if you pass
the ``-f`` option to the main.py script the UI will take up the full screen
at the highest available resolution. The window is divided into two (or
three in fullscreen) vertical "tracks", and the number and width of the
tracks are fixed at start up. (Feel free to edit the values in main.py to
play around with different track configurations.) Each track gets divided
horizontally into zero or more "viewers" (like windows in a windowed GUI,
cf. Chapter 4 of "Project Oberon") for a kind of tiled layout.
Currently, there are only two kinds of (interesting) viewers: TextViewers
and StackViewer. The TextViewers are crude text editors. They provide
just enough functionality to let the user write text and code (Python and
Joy) and execute Joy functions. One important thing they do is
automatically save their content after changes. No more lost work.
The StackViewer is a specialized TextViewer that shows the contents of the
Joy stack one line per stack item. It's a very handy visual aid to keep
track of what's going on. There's also a log.txt file that gets written
to when commands are executed, and so records the log of user actions and
system events. It tends to fill up quickly so there's a reset_log command
that clears it out.
Viewers have "grow" and "close" in their menu bars. These are buttons.
When you right-click on grow a viewer a copy is created that covers that
viewer's entire track. If you grow a viewer that already takes up its
whole track then a copy is created that takes up an additional track, up
to the whole screen. Closing a viewer just deletes that viewer, and when
a track has no more viewers, it is deleted and that exposes any previous
tracks and viewers that were hidden.
(Note: if you ever close all the viewers and are sitting at a blank screen
with nowhere to type and execute commands, press the Pause/Break key.
This will open a new "trap" viewer which you can then use to recover.)
Copies of a viewer all share the same model and update their display as it
changes. (If you have two viewers open on the same named resource and edit
one you'll see the other update as you type.)
UI Guide
-----------------------------
left mouse sets cursor in text, in menu bar resizes viewer interactively
(this is a little buggy in that you can move the mouse quickly and get
outside the menu, leaving the viewer in the "resizing" state. Until I fix
this, the workaround is to just grab the menu bar again and wiggle it a
few pixels and let go. This will reset the machinery.)
Right mouse executes Joy command (functions), and you can drag with the
right button to highlight (well, underline) commands. Words that aren't
names of Joy commands won't be underlined. Release the button to execute
the command.
The middle mouse button (usually a wheel these days) scrolls the text but
you can also click and drag any viewer with it to move that viewer to
another track or to a different location in the same track. There's no
direct visual feedback for this (yet) but that dosen't seem to impair its
usefulness.
F1, F2 - set selection begin and end markers (crude but usable.)
F3 - copy selected text to the top of the stack.
Shift-F3 - as copy then run "parse" command on the string.
F4 - cut selected text to the top of the stack.
Shift-F4 - as cut then run "pop" (delete selection.)
Joy
----------------------------
Pretty much all of the rest of the functionality of the system is provided
by executing Joy commands (aka functions, aka "words" in Forth) by right-
clicking on their names in any text.
To get help on a Joy function select the name of the function in a
TextViewer using F1 and F2, then press shift-F3 to parse the selection.
The function (really its Symbol) will appear on the stack in brackets (a
"quoted program" such as "[pop]".) Then right-click on the word help in
any TextViewer (if it's not already there, just type it in somewhere.)
This will print the docstring or definition of the word (function) to
stdout. At some point I'll write a thing to send that to the log.txt file
instead, but for now look for output in the terminal.
Modules
-----------------------------
.. image:: _static/packages_Vui.png
.. toctree::
:maxdepth: 2
:caption: Contents:
core
main
display
viewer
text_viewer
stack_viewer
persist_task
Indices and tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.main
:members:

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.persist_task
:members:

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.stack_viewer
:members:

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.text_viewer
:members:

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.viewer
:members:

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

View File

@ -0,0 +1,693 @@
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
font-size: 17px;
background-color: #fff;
color: #000;
margin: 0;
padding: 0;
}
div.document {
width: 940px;
margin: 30px auto 0 auto;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 220px;
}
div.sphinxsidebar {
width: 220px;
font-size: 14px;
line-height: 1.5;
}
hr {
border: 1px solid #B1B4B6;
}
div.body {
background-color: #fff;
color: #3E4349;
padding: 0 30px 0 30px;
}
div.body > .section {
text-align: left;
}
div.footer {
width: 940px;
margin: 20px auto 30px auto;
font-size: 14px;
color: #888;
text-align: right;
}
div.footer a {
color: #888;
}
p.caption {
font-family: inherit;
font-size: inherit;
}
div.relations {
display: none;
}
div.sphinxsidebar a {
color: #444;
text-decoration: none;
border-bottom: 1px dotted #999;
}
div.sphinxsidebar a:hover {
border-bottom: 1px solid #999;
}
div.sphinxsidebarwrapper {
padding: 18px 10px;
}
div.sphinxsidebarwrapper p.logo {
padding: 0;
margin: -10px 0 0 0px;
text-align: center;
}
div.sphinxsidebarwrapper h1.logo {
margin-top: -10px;
text-align: center;
margin-bottom: 5px;
text-align: left;
}
div.sphinxsidebarwrapper h1.logo-name {
margin-top: 0px;
}
div.sphinxsidebarwrapper p.blurb {
margin-top: 0;
font-style: normal;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: 'Garamond', 'Georgia', serif;
color: #444;
font-size: 24px;
font-weight: normal;
margin: 0 0 5px 0;
padding: 0;
}
div.sphinxsidebar h4 {
font-size: 20px;
}
div.sphinxsidebar h3 a {
color: #444;
}
div.sphinxsidebar p.logo a,
div.sphinxsidebar h3 a,
div.sphinxsidebar p.logo a:hover,
div.sphinxsidebar h3 a:hover {
border: none;
}
div.sphinxsidebar p {
color: #555;
margin: 10px 0;
}
div.sphinxsidebar ul {
margin: 10px 0;
padding: 0;
color: #000;
}
div.sphinxsidebar ul li.toctree-l1 > a {
font-size: 120%;
}
div.sphinxsidebar ul li.toctree-l2 > a {
font-size: 110%;
}
div.sphinxsidebar input {
border: 1px solid #CCC;
font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
font-size: 1em;
}
div.sphinxsidebar hr {
border: none;
height: 1px;
color: #AAA;
background: #AAA;
text-align: left;
margin-left: 0;
width: 50%;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #004B6B;
text-decoration: underline;
}
a:hover {
color: #6D4100;
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Garamond', 'Georgia', serif;
font-weight: normal;
margin: 30px 0px 10px 0px;
padding: 0;
}
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
div.body h2 { font-size: 180%; }
div.body h3 { font-size: 150%; }
div.body h4 { font-size: 130%; }
div.body h5 { font-size: 100%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #DDD;
padding: 0 4px;
text-decoration: none;
}
a.headerlink:hover {
color: #444;
background: #EAEAEA;
}
div.body p, div.body dd, div.body li {
line-height: 1.4em;
}
div.admonition {
margin: 20px 0px;
padding: 10px 30px;
background-color: #EEE;
border: 1px solid #CCC;
}
div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
background-color: ;
border-bottom: 1px solid #fafafa;
}
dd div.admonition {
margin-left: -60px;
padding-left: 60px;
}
div.admonition p.admonition-title {
font-family: 'Garamond', 'Georgia', serif;
font-weight: normal;
font-size: 24px;
margin: 0 0 10px 0;
padding: 0;
line-height: 1;
}
div.admonition p.last {
margin-bottom: 0;
}
div.highlight {
background-color: #fff;
}
dt:target, .highlight {
background: #FAF3E8;
}
div.warning {
background-color: #FCC;
border: 1px solid #FAA;
}
div.danger {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.error {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.caution {
background-color: #FCC;
border: 1px solid #FAA;
}
div.attention {
background-color: #FCC;
border: 1px solid #FAA;
}
div.important {
background-color: #EEE;
border: 1px solid #CCC;
}
div.note {
background-color: #EEE;
border: 1px solid #CCC;
}
div.tip {
background-color: #EEE;
border: 1px solid #CCC;
}
div.hint {
background-color: #EEE;
border: 1px solid #CCC;
}
div.seealso {
background-color: #EEE;
border: 1px solid #CCC;
}
div.topic {
background-color: #EEE;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre, tt, code {
font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.9em;
}
.hll {
background-color: #FFC;
margin: 0 -12px;
padding: 0 12px;
display: block;
}
img.screenshot {
}
tt.descname, tt.descclassname, code.descname, code.descclassname {
font-size: 0.95em;
}
tt.descname, code.descname {
padding-right: 0.08em;
}
img.screenshot {
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils {
border: 1px solid #888;
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils td, table.docutils th {
border: 1px solid #888;
padding: 0.25em 0.7em;
}
table.field-list, table.footnote {
border: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
table.footnote {
margin: 15px 0;
width: 100%;
border: 1px solid #EEE;
background: #FDFDFD;
font-size: 0.9em;
}
table.footnote + table.footnote {
margin-top: -15px;
border-top: none;
}
table.field-list th {
padding: 0 0.8em 0 0;
}
table.field-list td {
padding: 0;
}
table.field-list p {
margin-bottom: 0.8em;
}
table.footnote td.label {
width: .1px;
padding: 0.3em 0 0.3em 0.5em;
}
table.footnote td {
padding: 0.3em 0.5em;
}
dl {
margin: 0;
padding: 0;
}
dl dd {
margin-left: 30px;
}
blockquote {
margin: 0 0 0 30px;
padding: 0;
}
ul, ol {
/* Matches the 30px from the narrow-screen "li > ul" selector below */
margin: 10px 0 10px 30px;
padding: 0;
}
pre {
background: #EEE;
padding: 7px 30px;
margin: 15px 0px;
line-height: 1.3em;
}
div.viewcode-block:target {
background: #ffd;
}
dl pre, blockquote pre, li pre {
margin-left: 0;
padding-left: 30px;
}
dl dl pre {
margin-left: -90px;
padding-left: 90px;
}
tt, code {
background-color: #ecf0f3;
color: #222;
/* padding: 1px 2px; */
}
tt.xref, code.xref, a tt {
background-color: #FBFBFB;
border-bottom: 1px solid #fff;
}
a.reference {
text-decoration: none;
border-bottom: 1px dotted #004B6B;
}
/* Don't put an underline on images */
a.image-reference, a.image-reference:hover {
border-bottom: none;
}
a.reference:hover {
border-bottom: 1px solid #6D4100;
}
a.footnote-reference {
text-decoration: none;
font-size: 0.7em;
vertical-align: top;
border-bottom: 1px dotted #004B6B;
}
a.footnote-reference:hover {
border-bottom: 1px solid #6D4100;
}
a:hover tt, a:hover code {
background: #EEE;
}
@media screen and (max-width: 870px) {
div.sphinxsidebar {
display: none;
}
div.document {
width: 100%;
}
div.documentwrapper {
margin-left: 0;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
}
div.bodywrapper {
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
}
ul {
margin-left: 0;
}
li > ul {
/* Matches the 30px from the "ul, ol" selector above */
margin-left: 30px;
}
.document {
width: auto;
}
.footer {
width: auto;
}
.bodywrapper {
margin: 0;
}
.footer {
width: auto;
}
.github {
display: none;
}
}
@media screen and (max-width: 875px) {
body {
margin: 0;
padding: 20px 30px;
}
div.documentwrapper {
float: none;
background: #fff;
}
div.sphinxsidebar {
display: block;
float: none;
width: 102.5%;
margin: 50px -30px -20px -30px;
padding: 10px 20px;
background: #333;
color: #FFF;
}
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
div.sphinxsidebar h3 a {
color: #fff;
}
div.sphinxsidebar a {
color: #AAA;
}
div.sphinxsidebar p.logo {
display: none;
}
div.document {
width: 100%;
margin: 0;
}
div.footer {
display: none;
}
div.bodywrapper {
margin: 0;
}
div.body {
min-height: 0;
padding: 0;
}
.rtd_doc_footer {
display: none;
}
.document {
width: auto;
}
.footer {
width: auto;
}
.footer {
width: auto;
}
.github {
display: none;
}
}
/* misc. */
.revsys-inline {
display: none!important;
}
/* Make nested-list/multi-paragraph items look better in Releases changelog
* pages. Without this, docutils' magical list fuckery causes inconsistent
* formatting between different release sub-lists.
*/
div#changelog > div.section > ul > li > p:only-child {
margin-bottom: 0;
}
/* Hide fugly table cell borders in ..bibliography:: directive output */
table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
border: none;
/* Below needed in some edge cases; if not applied, bottom shadows appear */
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}

View File

@ -0,0 +1,676 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
word-wrap: break-word;
overflow-wrap : break-word;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
padding: 0.25em;
box-sizing: border-box;
}
div.sphinxsidebar #searchbox input[type="submit"] {
float: left;
width: 20%;
border-left: none;
padding: 0.25em;
box-sizing: border-box;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
margin-left: auto;
margin-right: auto;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable ul {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}
table.indextable > tbody > tr > td > ul {
padding-left: 0em;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- domain module index --------------------------------------------------- */
table.modindextable td {
padding: 2px;
border-collapse: collapse;
}
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: 450px;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink,
caption:hover > a.headerlink,
p.caption:hover > a.headerlink,
div.code-block-caption:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
table caption span.caption-text {
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
/* -- figures --------------------------------------------------------------- */
div.figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption {
padding: 0.3em;
}
div.figure p.caption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
table.field-list td, table.field-list th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist td {
vertical-align: top;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
div.code-block-caption {
padding: 2px 5px;
font-size: small;
}
div.code-block-caption code {
background-color: transparent;
}
div.code-block-caption + div > div.highlight > pre {
margin-top: 0;
}
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
}
div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
padding: 1em 1em 0;
}
div.literal-block-wrapper div.highlight {
margin: 0;
}
code.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
code.descclassname {
background-color: transparent;
}
code.xref, a code {
background-color: transparent;
font-weight: bold;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
span.eqno a.headerlink {
position: relative;
left: 0px;
z-index: 1;
}
div.math:hover a.headerlink {
visibility: visible;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

View File

@ -0,0 +1 @@
/* This file intentionally left blank. */

View File

@ -0,0 +1,315 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var bbox = span.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
var parentOfText = node.parentNode.parentNode;
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated === 'undefined')
return string;
return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this === '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
},
initOnKeyListeners: function() {
$(document).keyup(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box or textarea
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
if (prevHref) {
window.location.href = prevHref;
return false;
}
case 39: // right
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
}
}
}
});
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

View File

@ -0,0 +1,10 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.1',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,297 @@
/*
* language_data.js
* ~~~~~~~~~~~~~~~~
*
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
/* Non-minified version JS is _stemmer.js if file is provided */
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
var splitChars = (function() {
var result = {};
var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
var i, j, start, end;
for (i = 0; i < singles.length; i++) {
result[singles[i]] = true;
}
var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
[722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
[1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
[1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
[1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
[2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
[2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
[2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
[2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
[2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
[2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
[2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
[3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
[3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
[3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
[3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
[3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
[3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
[4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
[4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
[4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
[4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
[5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
[6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
[6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
[6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
[6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
[7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
[7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
[8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
[8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
[8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
[10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
[11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
[12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
[12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
[12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
[19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
[42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
[42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
[43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
[43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
[43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
[43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
[44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
[57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
[64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
[65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
[65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
for (i = 0; i < ranges.length; i++) {
start = ranges[i][0];
end = ranges[i][1];
for (j = start; j <= end; j++) {
result[j] = true;
}
}
return result;
})();
function splitQuery(query) {
var result = [];
var start = -1;
for (var i = 0; i < query.length; i++) {
if (splitChars[query.charCodeAt(i)]) {
if (start !== -1) {
result.push(query.slice(start, i));
start = -1;
}
} else if (start === -1) {
start = i;
}
}
if (start !== -1) {
result.push(query.slice(start));
}
return result;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

View File

@ -0,0 +1,65 @@
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #FF0000; background-color: #FFAAAA } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .o { color: #333333 } /* Operator */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #557799 } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #003388; font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #333399; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #6600EE; font-weight: bold } /* Literal.Number */
.highlight .s { background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #0000CC } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #BB0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #880000; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #FF0000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066BB; font-weight: bold } /* Name.Function */
.highlight .nl { color: #997700; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #007700 } /* Name.Tag */
.highlight .nv { color: #996633 } /* Name.Variable */
.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #6600EE; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #6600EE; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #005588; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #4400EE; font-weight: bold } /* Literal.Number.Oct */
.highlight .sb { background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #0044DD } /* Literal.String.Char */
.highlight .sd { color: #DD4422 } /* Literal.String.Doc */
.highlight .s2 { background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #666666; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { background-color: #eeeeee } /* Literal.String.Interpol */
.highlight .sx { color: #DD2200; background-color: #fff0f0 } /* Literal.String.Other */
.highlight .sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #AA6600 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700; font-weight: bold } /* Name.Variable.Global */
.highlight .vi { color: #3333BB } /* Name.Variable.Instance */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */

View File

@ -0,0 +1,481 @@
/*
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
if (!Scorer) {
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
// query found in terms
term: 5
};
}
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null,
dataType: "script", cache: true,
complete: function(jqxhr, textstatus) {
if (textstatus != "success") {
document.getElementById("searchindexloader").src = url;
}
}});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
var i;
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
}
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
/**
* execute search (requires search index to be loaded)
*/
query : function(query) {
var i;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = splitQuery(query);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
// prevent stemmer from cutting word smaller than two chars
if(word.length < 3 && tmp[i].length >= 3) {
word = tmp[i];
}
var toAppend;
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
}
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var terms = this._index.terms;
var titleterms = this._index.titleterms;
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(this.performObjectSearch(objectterms[i], others));
}
// lookup as search terms in fulltext
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
}
});
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
listItem.append($('<a/>').attr('href',
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
highlightstring + item[2]).html(item[1]));
} else {
// normal html builders
listItem.append($('<a/>').attr('href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
}
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
if (suffix === undefined) {
suffix = '.txt';
}
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
}
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}});
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
/**
* search for object names
*/
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var docnames = this._index.docnames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var i;
var results = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
var score = 0;
var parts = fullname.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullname == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
var anchor = match[3];
if (anchor === '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2])) {
score += Scorer.objPrio[match[2]];
} else {
score += Scorer.objPrioDefault;
}
results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
}
}
}
return results;
},
/**
* search for full-text terms in the index
*/
performTermsSearch : function(searchterms, excluded, terms, titleterms) {
var docnames = this._index.docnames;
var filenames = this._index.filenames;
var titles = this._index.titles;
var i, j, file;
var fileMap = {};
var scoreMap = {};
var results = [];
// perform the search on the required terms
for (i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
var files = [];
var _o = [
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
];
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
break;
}
// found search word in contents
$u.each(_o, function(o) {
var _files = o.files;
if (_files === undefined)
return
if (_files.length === undefined)
_files = [_files];
files = files.concat(_files);
// set score for the word in each file to Scorer.term
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {}
scoreMap[file][word] = o.score;
}
});
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
titleterms[excluded[i]] == file ||
$u.contains(terms[excluded[i]] || [], file) ||
$u.contains(titleterms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it to the result list
if (valid) {
// select one (max) score for the file.
// for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
}
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
makeSearchSummary : function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
};
$(document).ready(function() {
Search.init();
});

View File

@ -0,0 +1,999 @@
// Underscore.js 1.3.1
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function() {
// Baseline setup
// --------------
// Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
var slice = ArrayProto.slice,
unshift = ArrayProto.unshift,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler "advanced" mode.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root['_'] = _;
}
// Current version.
_.VERSION = '1.3.1';
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results[results.length] = iterator.call(context, value, index, list);
});
if (obj.length === +obj.length) results.length = obj.length;
return results;
};
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
}
});
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var reversed = _.toArray(obj).reverse();
if (context && !initial) iterator = _.bind(iterator, context);
return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
};
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) {
var result;
any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
each(obj, function(value, index, list) {
if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, iterator, context) {
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return result;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
// Determine if a given value is included in the array or object using `===`.
// Aliased as `contains`.
_.include = _.contains = function(obj, target) {
var found = false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
found = any(obj, function(value) {
return value === target;
});
return found;
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
return _.map(obj, function(value) {
return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
});
};
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; });
};
// Return the maximum element or (element-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Shuffle an array.
_.shuffle = function(obj) {
var shuffled = [], rand;
each(obj, function(value, index, list) {
if (index == 0) {
shuffled[0] = value;
} else {
rand = Math.floor(Math.random() * (index + 1));
shuffled[index] = shuffled[rand];
shuffled[rand] = value;
}
});
return shuffled;
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
return _.pluck(_.map(obj, function(value, index, list) {
return {
value : value,
criteria : iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}), 'value');
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {
var key = iterator(value, index);
(result[key] || (result[key] = [])).push(value);
});
return result;
};
// Use a comparator function to figure out at what index an object should
// be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator) {
iterator || (iterator = _.identity);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >> 1;
iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
}
return low;
};
// Safely convert anything iterable into a real, live array.
_.toArray = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) return iterable.toArray();
if (_.isArray(iterable)) return slice.call(iterable);
if (_.isArguments(iterable)) return slice.call(iterable);
return _.values(iterable);
};
// Return the number of elements in an object.
_.size = function(obj) {
return _.toArray(obj).length;
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head`. The **guard** check allows it to work
// with `_.map`.
_.first = _.head = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
// Returns everything but the last entry of the array. Especcialy useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
if ((n != null) && !guard) {
return slice.call(array, Math.max(array.length - n, 0));
} else {
return array[array.length - 1];
}
};
// Returns everything but the first entry of the array. Aliased as `tail`.
// Especially useful on the arguments object. Passing an **index** will return
// the rest of the values in the array from that index onward. The **guard**
// check allows it to work with `_.map`.
_.rest = _.tail = function(array, index, guard) {
return slice.call(array, (index == null) || guard ? 1 : index);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, function(value){ return !!value; });
};
// Return a completely flattened version of an array.
_.flatten = function(array, shallow) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
memo[memo.length] = value;
return memo;
}, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
return _.difference(array, slice.call(arguments, 1));
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator) {
var initial = iterator ? _.map(array, iterator) : array;
var result = [];
_.reduce(initial, function(memo, el, i) {
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
memo[memo.length] = el;
result[result.length] = array[i];
}
return memo;
}, []);
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays. (Aliased as "intersect" for back-compat.)
_.intersection = _.intersect = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0;
});
});
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_.difference = function(array) {
var rest = _.flatten(slice.call(arguments, 1));
return _.filter(array, function(value){ return !_.include(rest, value); });
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
return results;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i, l;
if (isSorted) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item) {
if (array == null) return -1;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
var i = array.length;
while (i--) if (i in array && array[i] === item) return i;
return -1;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
_.range = function(start, stop, step) {
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
var len = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(len);
while(idx < len) {
range[idx++] = start;
start += step;
}
return range;
};
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};
};
// Bind all of an object's methods to that object. Useful for ensuring that
// all callbacks defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length == 0) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
};
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(func, args); }, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
var context, args, timeout, throttling, more;
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
return function() {
context = this; args = arguments;
var later = function() {
timeout = null;
if (more) func.apply(context, args);
whenDone();
};
if (!timeout) timeout = setTimeout(later, wait);
if (throttling) {
more = true;
} else {
func.apply(context, args);
}
whenDone();
throttling = true;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds.
_.debounce = function(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
return memo = func.apply(this, arguments);
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
return function() {
var args = [func].concat(slice.call(arguments, 0));
return wrapper.apply(this, args);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = arguments;
return function() {
var args = arguments;
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
};
};
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
if (times <= 0) return func();
return function() {
if (--times < 1) { return func.apply(this, arguments); }
};
};
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
return _.map(obj, _.identity);
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
obj[prop] = source[prop];
}
});
return obj;
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop];
}
});
return obj;
};
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
// Internal recursive comparison function.
function eq(a, b, stack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
if (a === b) return a !== 0 || 1 / a == 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
if (a._chain) a = a._wrapped;
if (b._chain) b = b._wrapped;
// Invoke a custom `isEqual` method if one is provided.
if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(b);
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a == +b;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
}
if (typeof a != 'object' || typeof b != 'object') return false;
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
var length = stack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (stack[length] == a) return true;
}
// Add the first object to the stack of traversed objects.
stack.push(a);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
// Ensure commutative equality for sparse arrays.
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
}
}
} else {
// Objects with different constructors are not equivalent.
if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (_.has(b, key) && !(size--)) break;
}
result = !size;
}
}
// Remove the first object from the stack of traversed objects.
stack.pop();
return result;
}
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, []);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (_.has(obj, key)) return false;
return true;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType == 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
};
// Is a given variable an arguments object?
_.isArguments = function(obj) {
return toString.call(obj) == '[object Arguments]';
};
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
};
}
// Is a given value a function?
_.isFunction = function(obj) {
return toString.call(obj) == '[object Function]';
};
// Is a given value a string?
_.isString = function(obj) {
return toString.call(obj) == '[object String]';
};
// Is a given value a number?
_.isNumber = function(obj) {
return toString.call(obj) == '[object Number]';
};
// Is the given value `NaN`?
_.isNaN = function(obj) {
// `NaN` is the only value for which `===` is not reflexive.
return obj !== obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
// Is a given value a date?
_.isDate = function(obj) {
return toString.call(obj) == '[object Date]';
};
// Is the given value a regular expression?
_.isRegExp = function(obj) {
return toString.call(obj) == '[object RegExp]';
};
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
};
// Is a given variable undefined?
_.isUndefined = function(obj) {
return obj === void 0;
};
// Has own property?
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
return this;
};
// Keep the identity function around for default iterators.
_.identity = function(value) {
return value;
};
// Run a function **n** times.
_.times = function (n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i);
};
// Escape a string for HTML interpolation.
_.escape = function(string) {
return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
each(_.functions(obj), function(name){
addToWrapper(name, _[name] = obj[name]);
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = idCounter++;
return prefix ? prefix + id : id;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /.^/;
// Within an interpolation, evaluation, or escaping, remove HTML escaping
// that had been previously added.
var unescape = function(code) {
return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(str, data) {
var c = _.templateSettings;
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
'with(obj||{}){__p.push(\'' +
str.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(c.escape || noMatch, function(match, code) {
return "',_.escape(" + unescape(code) + "),'";
})
.replace(c.interpolate || noMatch, function(match, code) {
return "'," + unescape(code) + ",'";
})
.replace(c.evaluate || noMatch, function(match, code) {
return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
})
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
+ "');}return __p.join('');";
var func = new Function('obj', '_', tmpl);
if (data) return func(data, _);
return function(data) {
return func.call(this, data, _);
};
};
// Add a "chain" function, which will delegate to the wrapper.
_.chain = function(obj) {
return _(obj).chain();
};
// The OOP Wrapper
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };
// Expose `wrapper.prototype` as `_.prototype`
_.prototype = wrapper.prototype;
// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
};
// A method to easily add functions to the OOP wrapper.
var addToWrapper = function(name, func) {
wrapper.prototype[name] = function() {
var args = slice.call(arguments);
unshift.call(args, this._wrapped);
return result(func.apply(_, args), this._chain);
};
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
var wrapped = this._wrapped;
method.apply(wrapped, arguments);
var length = wrapped.length;
if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
return result(wrapped, this._chain);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
});
// Start chaining a wrapped Underscore object.
wrapper.prototype.chain = function() {
this._chain = true;
return this;
};
// Extracts the result from a wrapped and chained object.
wrapper.prototype.value = function() {
return this._wrapped;
};
}).call(this);

View File

@ -0,0 +1,31 @@
// Underscore.js 1.3.1
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),
function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

View File

@ -0,0 +1,808 @@
/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilities for all documentation.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$(document).on("click", 'a.comment-close', function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$(document).on("click", 'a.vote', function(event) {
event.preventDefault();
handleVote($(this));
});
$(document).on("click", 'a.reply', function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.close-reply', function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.sort-option', function(event) {
event.preventDefault();
handleReSort($(this));
});
$(document).on("click", 'a.show-proposal', function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-proposal', function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.show-propose-change', function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-propose-change', function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.accept-comment', function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.delete-comment', function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.comment-markup', function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('<li>No comments yet.</li>');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(var i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; i<classes.length; i++) {
if (classes[i] != 'sort-option') {
by = classes[i].substring(2);
}
}
setComparator();
// Save/update the sortBy cookie.
var expiration = new Date();
expiration.setDate(expiration.getDate() + 365);
document.cookie= 'sortBy=' + escape(by) +
';expires=' + expiration.toUTCString();
$('ul.comment-ul').each(function(index, ul) {
var comments = getChildren($(ul), true);
comments = sortComments(comments);
appendComments(comments, $(ul).empty());
});
}
/**
* Function to process a vote when a user clicks an arrow.
*/
function handleVote(link) {
if (!opts.voting) {
showError("You'll need to login to vote.");
return;
}
var id = link.attr('id');
if (!id) {
// Didn't click on one of the voting arrows.
return;
}
// If it is an unvote, the new vote value is 0,
// Otherwise it's 1 for an upvote, or -1 for a downvote.
var value = 0;
if (id.charAt(1) != 'u') {
value = id.charAt(0) == 'u' ? 1 : -1;
}
// The data to be sent to the server.
var d = {
comment_id: id.substring(2),
value: value
};
// Swap the vote and unvote links.
link.hide();
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
.show();
// The div the comment is displayed in.
var div = $('div#cd' + d.comment_id);
var data = div.data('comment');
// If this is not an unvote, and the other vote arrow has
// already been pressed, unpress it.
if ((d.value !== 0) && (data.vote === d.value * -1)) {
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
}
// Update the comments rating in the local data.
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
data.vote = d.value;
div.data('comment', data);
// Change the rating text.
div.find('.rating:first')
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
// Send the vote information to the server.
$.ajax({
type: "POST",
url: opts.processVoteURL,
data: d,
error: function(request, textStatus, error) {
showError('Oops, there was a problem casting that vote.');
}
});
}
/**
* Open a reply form used to reply to an existing comment.
*/
function openReply(id) {
// Swap out the reply link for the hide link
$('#rl' + id).hide();
$('#cr' + id).show();
// Add the reply li to the children ul.
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
$('#cl' + id)
.prepend(div)
// Setup the submit handler for the reply form.
.find('#rf' + id)
.submit(function(event) {
event.preventDefault();
addComment($('#rf' + id));
closeReply(id);
})
.find('input[type=button]')
.click(function() {
closeReply(id);
});
div.slideDown('fast', function() {
$('#rf' + id).find('textarea').focus();
});
}
/**
* Close the reply form opened with openReply.
*/
function closeReply(id) {
// Remove the reply div from the DOM.
$('#rd' + id).slideUp('fast', function() {
$(this).remove();
});
// Swap out the hide link for the reply link
$('#cr' + id).hide();
$('#rl' + id).show();
}
/**
* Recursively sort a tree of comments using the comp comparator.
*/
function sortComments(comments) {
comments.sort(comp);
$.each(comments, function() {
this.children = sortComments(this.children);
});
return comments;
}
/**
* Get the children comments from a ul. If recursive is true,
* recursively include childrens' children.
*/
function getChildren(ul, recursive) {
var children = [];
ul.children().children("[id^='cd']")
.each(function() {
var comment = $(this).data('comment');
if (recursive)
comment.children = getChildren($(this).find('#cl' + comment.id), true);
children.push(comment);
});
return children;
}
/** Create a div to display a comment in. */
function createCommentDiv(comment) {
if (!comment.displayed && !opts.moderator) {
return $('<div class="moderate">Thank you! Your comment will show up '
+ 'once it is has been approved by a moderator.</div>');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
<div class="sphinx-comments" id="sc<%id%>">\
<p class="sort-options">\
Sort by:\
<a href="#" class="sort-option byrating">best rated</a>\
<a href="#" class="sort-option byascage">newest</a>\
<a href="#" class="sort-option byage">oldest</a>\
</p>\
<div class="comment-header">Comments</div>\
<div class="comment-loading" id="cn<%id%>">\
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
<ul id="cl<%id%>" class="comment-ul"></ul>\
<div id="ca<%id%>">\
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
<code>``code``</code>, \
code blocks: <code>::</code> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
<a href="#" id="pc<%id%>" class="show-propose-change">\
Propose a change &#9657;\
</a>\
<a href="#" id="hc<%id%>" class="hide-propose-change">\
Propose a change &#9663;\
</a>\
</p>\
<textarea name="proposal" id="pt<%id%>" cols="80"\
spellcheck="false"></textarea>\
<input type="submit" value="Add comment" />\
<input type="hidden" name="node" value="<%id%>" />\
<input type="hidden" name="parent" value="" />\
</form>\
</div>\
</div>';
var commentTemplate = '\
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
<div class="vote">\
<div class="arrow">\
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
<img src="<%upArrow%>" />\
</a>\
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
<img src="<%upArrowPressed%>" />\
</a>\
</div>\
<div class="arrow">\
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
<img src="<%downArrow%>" id="da<%id%>" />\
</a>\
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
<img src="<%downArrowPressed%>" />\
</a>\
</div>\
</div>\
<div class="comment-content">\
<p class="tagline comment">\
<span class="user-id"><%username%></span>\
<span class="rating"><%pretty_rating%></span>\
<span class="delta"><%time.delta%></span>\
</p>\
<div class="comment-text comment"><#text#></div>\
<p class="comment-opts comment">\
<a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
<a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
<a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
<a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
<span id="cm<%id%>" class="moderation hidden">\
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
</span>\
</p>\
<pre class="proposal" id="pr<%id%>">\
<#proposal_diff#>\
</pre>\
<ul class="comment-children" id="cl<%id%>"></ul>\
</div>\
<div class="clearleft"></div>\
</div>\
</div>';
var replyTemplate = '\
<li>\
<div class="reply-div" id="rd<%id%>">\
<form id="rf<%id%>">\
<textarea name="comment" cols="80"></textarea>\
<input type="submit" value="Add reply" />\
<input type="button" value="Cancel" />\
<input type="hidden" name="parent" value="<%id%>" />\
<input type="hidden" name="node" value="" />\
</form>\
</div>\
</li>';
$(document).ready(function() {
init();
});
})(jQuery);
$(document).ready(function() {
// add comment anchors for all paragraphs that are commentable
$('.sphinx-has-comment').comment();
// highlight search words in search results
$("div.context").each(function() {
var params = $.getQueryParameters();
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
var result = $(this);
$.each(terms, function() {
result.highlightText(this.toLowerCase(), 'highlighted');
});
});
// directly open comment window if requested
var anchor = document.location.hash;
if (anchor.substring(0, 9) == '#comment-') {
$('#ao' + anchor.substring(9)).click();
document.location.hash = '#s' + anchor.substring(9);
}
});

View File

@ -0,0 +1,234 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Core &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Display" href="display.html" />
<link rel="prev" title="Welcome to Joy VUIs documentation!" href="index.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<span class="target" id="module-joy.vui.core"></span><div class="section" id="core">
<h1>Core<a class="headerlink" href="#core" title="Permalink to this headline"></a></h1>
<p>The core module defines a bunch of system-wide “constants” (some colors
and PyGame event groups), the message classes for Oberon-style message
passing, a “world” class that holds the main context for the system, and
a mainloop class that manages the, uh, main loop (the PyGame event queue.)</p>
<dl class="data">
<dt id="joy.vui.core.ARROW_KEYS">
<code class="descclassname">joy.vui.core.</code><code class="descname">ARROW_KEYS</code><em class="property"> = frozenset([273, 274, 275, 276])</em><a class="headerlink" href="#joy.vui.core.ARROW_KEYS" title="Permalink to this definition"></a></dt>
<dd><p>PyGame arrow key events.</p>
</dd></dl>
<dl class="data">
<dt id="joy.vui.core.AVAILABLE_TASK_EVENTS">
<code class="descclassname">joy.vui.core.</code><code class="descname">AVAILABLE_TASK_EVENTS</code><em class="property"> = set([24, 25, 26, 27, 28, 29, 30, 31])</em><a class="headerlink" href="#joy.vui.core.AVAILABLE_TASK_EVENTS" title="Permalink to this definition"></a></dt>
<dd><p>Task IDs that have not been assigned to a task.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.CommandMessage">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">CommandMessage</code><span class="sig-paren">(</span><em>sender</em>, <em>command</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#CommandMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.CommandMessage" title="Permalink to this definition"></a></dt>
<dd><p>For commands, adds <code class="docutils literal notranslate"><span class="pre">command</span></code> field.</p>
</dd></dl>
<dl class="data">
<dt id="joy.vui.core.MOUSE_EVENTS">
<code class="descclassname">joy.vui.core.</code><code class="descname">MOUSE_EVENTS</code><em class="property"> = frozenset([4, 5, 6])</em><a class="headerlink" href="#joy.vui.core.MOUSE_EVENTS" title="Permalink to this definition"></a></dt>
<dd><p>PyGame mouse events.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.Message">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">Message</code><span class="sig-paren">(</span><em>sender</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#Message"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.Message" title="Permalink to this definition"></a></dt>
<dd><p>Message base class. Contains <code class="docutils literal notranslate"><span class="pre">sender</span></code> field.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.ModifyMessage">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">ModifyMessage</code><span class="sig-paren">(</span><em>sender</em>, <em>subject</em>, <em>**details</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#ModifyMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.ModifyMessage" title="Permalink to this definition"></a></dt>
<dd><p>For when resources are modified, adds <code class="docutils literal notranslate"><span class="pre">subject</span></code> and <code class="docutils literal notranslate"><span class="pre">details</span></code>
fields.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.OpenMessage">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">OpenMessage</code><span class="sig-paren">(</span><em>sender</em>, <em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#OpenMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.OpenMessage" title="Permalink to this definition"></a></dt>
<dd><p>For when resources are modified, adds <code class="docutils literal notranslate"><span class="pre">name</span></code>, content_id``,
<code class="docutils literal notranslate"><span class="pre">status</span></code>, and <code class="docutils literal notranslate"><span class="pre">traceback</span></code> fields.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.PersistMessage">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">PersistMessage</code><span class="sig-paren">(</span><em>sender</em>, <em>content_id</em>, <em>**details</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#PersistMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.PersistMessage" title="Permalink to this definition"></a></dt>
<dd><p>For when resources are modified, adds <code class="docutils literal notranslate"><span class="pre">content_id</span></code> and <code class="docutils literal notranslate"><span class="pre">details</span></code>
fields.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.ShutdownMessage">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">ShutdownMessage</code><span class="sig-paren">(</span><em>sender</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#ShutdownMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.ShutdownMessage" title="Permalink to this definition"></a></dt>
<dd><p>Signals that the system is shutting down.</p>
</dd></dl>
<dl class="data">
<dt id="joy.vui.core.TASK_EVENTS">
<code class="descclassname">joy.vui.core.</code><code class="descname">TASK_EVENTS</code><em class="property"> = (24, 25, 26, 27, 28, 29, 30, 31)</em><a class="headerlink" href="#joy.vui.core.TASK_EVENTS" title="Permalink to this definition"></a></dt>
<dd><p>Keep track of all possible task events.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.TheLoop">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">TheLoop</code><span class="sig-paren">(</span><em>display</em>, <em>clock</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#TheLoop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.TheLoop" title="Permalink to this definition"></a></dt>
<dd><p>The main loop manages tasks and the PyGame event queue
and framerate clock.</p>
<dl class="method">
<dt id="joy.vui.core.TheLoop.install_task">
<code class="descname">install_task</code><span class="sig-paren">(</span><em>F</em>, <em>milliseconds</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#TheLoop.install_task"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.TheLoop.install_task" title="Permalink to this definition"></a></dt>
<dd><p>Install a task to run every so many milliseconds.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.core.TheLoop.loop">
<code class="descname">loop</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#TheLoop.loop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.TheLoop.loop" title="Permalink to this definition"></a></dt>
<dd><p>The actual main loop machinery.</p>
<p>Maintain a <code class="docutils literal notranslate"><span class="pre">running</span></code> flag, pump the PyGame event queue and
handle the events (dispatching to the display), tick the clock.</p>
<p>When the loop is exited (by clicking the window close button or
pressing the <code class="docutils literal notranslate"><span class="pre">escape</span></code> key) it broadcasts a <code class="docutils literal notranslate"><span class="pre">ShutdownMessage</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.core.TheLoop.remove_task">
<code class="descname">remove_task</code><span class="sig-paren">(</span><em>task_event_id</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#TheLoop.remove_task"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.TheLoop.remove_task" title="Permalink to this definition"></a></dt>
<dd><p>Remove an installed task.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.core.TheLoop.run_task">
<code class="descname">run_task</code><span class="sig-paren">(</span><em>task_event_id</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#TheLoop.run_task"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.TheLoop.run_task" title="Permalink to this definition"></a></dt>
<dd><p>Give a task its time to shine.</p>
</dd></dl>
</dd></dl>
<dl class="class">
<dt id="joy.vui.core.World">
<em class="property">class </em><code class="descclassname">joy.vui.core.</code><code class="descname">World</code><span class="sig-paren">(</span><em>stack_id</em>, <em>stack_holder</em>, <em>dictionary</em>, <em>notify</em>, <em>log</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#World"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.World" title="Permalink to this definition"></a></dt>
<dd><p>This object contains the system context, the stack, dictionary, a
reference to the display broadcast method, and the log.</p>
<dl class="method">
<dt id="joy.vui.core.World.handle">
<code class="descname">handle</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#World.handle"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.World.handle" title="Permalink to this definition"></a></dt>
<dd><p>Deal with updates to the stack and commands.</p>
</dd></dl>
</dd></dl>
<dl class="function">
<dt id="joy.vui.core.open_viewer_on_string">
<code class="descclassname">joy.vui.core.</code><code class="descname">open_viewer_on_string</code><span class="sig-paren">(</span><em>sender</em>, <em>content</em>, <em>notify</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#open_viewer_on_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.open_viewer_on_string" title="Permalink to this definition"></a></dt>
<dd><p>Helper function to open a text viewer on a string.
Typically used to show tracebacks.</p>
</dd></dl>
<dl class="function">
<dt id="joy.vui.core.push">
<code class="descclassname">joy.vui.core.</code><code class="descname">push</code><span class="sig-paren">(</span><em>sender</em>, <em>item</em>, <em>notify</em>, <em>stack_name='stack.pickle'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/core.html#push"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.core.push" title="Permalink to this definition"></a></dt>
<dd><p>Helper function to push an item onto the system stack with message.</p>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="index.html" title="previous chapter">Welcome to Joy VUIs documentation!</a></li>
<li>Next: <a href="display.html" title="next chapter">Display</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/core.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@ -0,0 +1,286 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Display &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Viewer" href="viewer.html" />
<link rel="prev" title="Core" href="core.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<span class="target" id="module-joy.vui.display"></span><div class="section" id="display">
<h1>Display<a class="headerlink" href="#display" title="Permalink to this headline"></a></h1>
<p>This module implements a simple visual display system modeled on Oberon.</p>
<p>Refer to Chapter 4 of the Project Oberon book for more information.</p>
<p>There is a Display object that manages a pygame surface and N vertical
tracks each of which manages zero or more viewers.</p>
<dl class="class">
<dt id="joy.vui.display.Display">
<em class="property">class </em><code class="descclassname">joy.vui.display.</code><code class="descname">Display</code><span class="sig-paren">(</span><em>screen</em>, <em>lookup</em>, <em>*track_ratios</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display" title="Permalink to this definition"></a></dt>
<dd><p>Manage tracks and viewers on a screen (Pygame surface.)</p>
<p>The size and number of tracks are defined by passing in at least two
ratios, e.g. Display(screen, 1, 4, 4) would create three tracks, one
small one on the left and two larger ones of the same size, each four
times wider than the left one.</p>
<p>All tracks take up the whole height of the display screen. Tracks
manage zero or more Viewers. When you “grow” a viewer a new track is
created that overlays or hides one or two existing tracks, and when
the last viewer in an overlay track is closed the track closes too
and reveals the hidden tracks (and their viewers, if any.)</p>
<p>In order to facilitate command underlining while mouse dragging the
lookup parameter must be a function that accepts a string and returns
a Boolean indicating whether that string is a valid Joy function name.
Typically you pass in the __contains__ method of the Joy dict. This
is a case of breaking “loose coupling” to gain efficiency, as otherwise
we would have to e.g. send some sort of lookup message to the
World context object, going through the whole Display.broadcast()
machinery, etc. Not something you want to do on each MOUSEMOTION
event.</p>
<dl class="method">
<dt id="joy.vui.display.Display.at">
<code class="descname">at</code><span class="sig-paren">(</span><em>x</em>, <em>y</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.at"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.at" title="Permalink to this definition"></a></dt>
<dd><p>Return the viewer (which can be a Track) at the x, y location,
along with the relative-to-viewer-surface x and y coordinates.
If there is no viewer at the location the Track will be returned
instead.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.broadcast">
<code class="descname">broadcast</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.broadcast"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.broadcast" title="Permalink to this definition"></a></dt>
<dd><p>Broadcast a message to all viewers (except the sender) and all
registered handlers.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.change_viewer">
<code class="descname">change_viewer</code><span class="sig-paren">(</span><em>viewer</em>, <em>y</em>, <em>relative=False</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.change_viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.change_viewer" title="Permalink to this definition"></a></dt>
<dd><p>Adjust the top of the viewer to a new y within the boundaries of
its neighbors.</p>
<p>If relative is False new_y should be in screen coords, else new_y
should be relative to the top of the viewer.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.close_viewer">
<code class="descname">close_viewer</code><span class="sig-paren">(</span><em>viewer</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.close_viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.close_viewer" title="Permalink to this definition"></a></dt>
<dd><p>Close the viewer.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.dispatch_event">
<code class="descname">dispatch_event</code><span class="sig-paren">(</span><em>event</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.dispatch_event"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.dispatch_event" title="Permalink to this definition"></a></dt>
<dd><p>Display event handling.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.done_resizing">
<code class="descname">done_resizing</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.done_resizing"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.done_resizing" title="Permalink to this definition"></a></dt>
<dd><p>Helper method called directly by <code class="docutils literal notranslate"><span class="pre">MenuViewer.mouse_up()</span></code> to (hackily)
update the display when done resizing a viewer.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.focus">
<code class="descname">focus</code><span class="sig-paren">(</span><em>viewer</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.focus"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.focus" title="Permalink to this definition"></a></dt>
<dd><p>Set system focus to a given viewer (or no viewer if a track.)</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.grow_viewer">
<code class="descname">grow_viewer</code><span class="sig-paren">(</span><em>viewer</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.grow_viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.grow_viewer" title="Permalink to this definition"></a></dt>
<dd><p>Cause the viewer to take up its whole track or, if it does
already, take up another track, up to the whole screen.</p>
<p>This is the inverse of closing a viewer. “Growing” a viewer
actually creates a new copy and a new track to hold it. The old
tracks and viewers are retained, and they get restored when the
covering track closes, which happens automatically when the last
viewer in the covering track is closed.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.init_text">
<code class="descname">init_text</code><span class="sig-paren">(</span><em>pt</em>, <em>x</em>, <em>y</em>, <em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.init_text"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.init_text" title="Permalink to this definition"></a></dt>
<dd><p>Open and return a <code class="docutils literal notranslate"><span class="pre">TextViewer</span></code> on a given file (which must be present
in the <code class="docutils literal notranslate"><span class="pre">JOYHOME</span></code> directory.)</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.iter_viewers">
<code class="descname">iter_viewers</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.iter_viewers"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.iter_viewers" title="Permalink to this definition"></a></dt>
<dd><p>Iterate through all viewers yielding (viewer, x, y) three-tuples.
The x and y coordinates are screen pixels of the top-left corner
of the viewer.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.open_viewer">
<code class="descname">open_viewer</code><span class="sig-paren">(</span><em>x</em>, <em>y</em>, <em>class_</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.open_viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.open_viewer" title="Permalink to this definition"></a></dt>
<dd><p>Open a viewer of <a href="#id1"><span class="problematic" id="id2">class_</span></a> at the x, y location on the display,
return the viewer.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Display.redraw">
<code class="descname">redraw</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Display.redraw"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Display.redraw" title="Permalink to this definition"></a></dt>
<dd><p>Redraw all tracks (which will redraw all viewers.)</p>
</dd></dl>
</dd></dl>
<dl class="class">
<dt id="joy.vui.display.Track">
<em class="property">class </em><code class="descclassname">joy.vui.display.</code><code class="descname">Track</code><span class="sig-paren">(</span><em>surface</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track" title="Permalink to this definition"></a></dt>
<dd><p>Manage a vertical strip of the display, and the viewers on it.</p>
<dl class="method">
<dt id="joy.vui.display.Track.broadcast">
<code class="descname">broadcast</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.broadcast"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.broadcast" title="Permalink to this definition"></a></dt>
<dd><p>Broadcast a message to all viewers on this track (except the sender.)</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Track.change_viewer">
<code class="descname">change_viewer</code><span class="sig-paren">(</span><em>viewer</em>, <em>new_y</em>, <em>relative=False</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.change_viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.change_viewer" title="Permalink to this definition"></a></dt>
<dd><p>Adjust the top of the viewer to a new y within the boundaries of
its neighbors.</p>
<p>If relative is False new_y should be in screen coords, else new_y
should be relative to the top of the viewer.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Track.close_viewer">
<code class="descname">close_viewer</code><span class="sig-paren">(</span><em>viewer</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.close_viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.close_viewer" title="Permalink to this definition"></a></dt>
<dd><p>Close the viewer, reuse the freed space.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Track.draw">
<code class="descname">draw</code><span class="sig-paren">(</span><em>rect=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.draw"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.draw" title="Permalink to this definition"></a></dt>
<dd><p>Draw the track onto its surface, clearing all content.</p>
<p>If rect is passed only draw to that area. This supports e.g.
closing a viewer that then exposes part of the track.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Track.open_viewer">
<code class="descname">open_viewer</code><span class="sig-paren">(</span><em>y</em>, <em>class_</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.open_viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.open_viewer" title="Permalink to this definition"></a></dt>
<dd><p>Open and return a viewer of class at y.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Track.redraw">
<code class="descname">redraw</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.redraw"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.redraw" title="Permalink to this definition"></a></dt>
<dd><p>Redraw the track and all of its viewers.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Track.split">
<code class="descname">split</code><span class="sig-paren">(</span><em>y</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.split"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.split" title="Permalink to this definition"></a></dt>
<dd><p>Split the Track at the y coordinate and return the height
available for a new viewer. Tracks manage a vertical strip of
the display screen so they dont resize their surface when split.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.display.Track.viewer_at">
<code class="descname">viewer_at</code><span class="sig-paren">(</span><em>y</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/display.html#Track.viewer_at"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.display.Track.viewer_at" title="Permalink to this definition"></a></dt>
<dd><p>Return the viewer at y along with the viewer-relative y coordinate,
if theres no viewer at y return this track and y.</p>
</dd></dl>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="core.html" title="previous chapter">Core</a></li>
<li>Next: <a href="viewer.html" title="next chapter">Viewer</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/display.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@ -0,0 +1,463 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="index">Index</h1>
<div class="genindex-jumpbox">
<a href="#A"><strong>A</strong></a>
| <a href="#B"><strong>B</strong></a>
| <a href="#C"><strong>C</strong></a>
| <a href="#D"><strong>D</strong></a>
| <a href="#E"><strong>E</strong></a>
| <a href="#F"><strong>F</strong></a>
| <a href="#G"><strong>G</strong></a>
| <a href="#H"><strong>H</strong></a>
| <a href="#I"><strong>I</strong></a>
| <a href="#J"><strong>J</strong></a>
| <a href="#L"><strong>L</strong></a>
| <a href="#M"><strong>M</strong></a>
| <a href="#O"><strong>O</strong></a>
| <a href="#P"><strong>P</strong></a>
| <a href="#R"><strong>R</strong></a>
| <a href="#S"><strong>S</strong></a>
| <a href="#T"><strong>T</strong></a>
| <a href="#V"><strong>V</strong></a>
| <a href="#W"><strong>W</strong></a>
</div>
<h2 id="A">A</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.ARROW_KEYS">ARROW_KEYS (in module joy.vui.core)</a>
</li>
<li><a href="display.html#joy.vui.display.Display.at">at() (joy.vui.display.Display method)</a>
<ul>
<li><a href="text_viewer.html#joy.vui.text_viewer.TextViewer.at">(joy.vui.text_viewer.TextViewer method)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.AVAILABLE_TASK_EVENTS">AVAILABLE_TASK_EVENTS (in module joy.vui.core)</a>
</li>
</ul></td>
</tr></table>
<h2 id="B">B</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.broadcast">broadcast() (joy.vui.display.Display method)</a>
<ul>
<li><a href="display.html#joy.vui.display.Track.broadcast">(joy.vui.display.Track method)</a>
</li>
</ul></li>
</ul></td>
</tr></table>
<h2 id="C">C</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.change_viewer">change_viewer() (joy.vui.display.Display method)</a>
<ul>
<li><a href="display.html#joy.vui.display.Track.change_viewer">(joy.vui.display.Track method)</a>
</li>
</ul></li>
<li><a href="persist_task.html#joy.vui.persist_task.check_filename">check_filename() (in module joy.vui.persist_task)</a>
</li>
<li><a href="text_viewer.html#joy.vui.text_viewer.TextViewer.close">close() (joy.vui.text_viewer.TextViewer method)</a>
<ul>
<li><a href="viewer.html#joy.vui.viewer.Viewer.close">(joy.vui.viewer.Viewer method)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.close_viewer">close_viewer() (joy.vui.display.Display method)</a>
<ul>
<li><a href="display.html#joy.vui.display.Track.close_viewer">(joy.vui.display.Track method)</a>
</li>
</ul></li>
<li><a href="core.html#joy.vui.core.CommandMessage">CommandMessage (class in joy.vui.core)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.commit">commit() (joy.vui.persist_task.PersistTask method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="D">D</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.dispatch_event">dispatch_event() (joy.vui.display.Display method)</a>
</li>
<li><a href="display.html#joy.vui.display.Display">Display (class in joy.vui.display)</a>
</li>
<li><a href="display.html#joy.vui.display.Display.done_resizing">done_resizing() (joy.vui.display.Display method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Track.draw">draw() (joy.vui.display.Track method)</a>
<ul>
<li><a href="viewer.html#joy.vui.viewer.MenuViewer.draw">(joy.vui.viewer.MenuViewer method)</a>
</li>
<li><a href="viewer.html#joy.vui.viewer.Viewer.draw">(joy.vui.viewer.Viewer method)</a>
</li>
</ul></li>
</ul></td>
</tr></table>
<h2 id="E">E</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="main.html#joy.vui.main.error_guard">error_guard() (in module joy.vui.main)</a>
</li>
</ul></td>
</tr></table>
<h2 id="F">F</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="main.html#joy.vui.main.FileFaker">FileFaker (class in joy.vui.main)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.focus">focus() (joy.vui.display.Display method)</a>
</li>
<li><a href="stack_viewer.html#joy.vui.stack_viewer.fsi">fsi() (in module joy.vui.stack_viewer)</a>
</li>
</ul></td>
</tr></table>
<h2 id="G">G</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.grow_viewer">grow_viewer() (joy.vui.display.Display method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="H">H</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.World.handle">handle() (joy.vui.core.World method)</a>
<ul>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.handle">(joy.vui.persist_task.PersistTask method)</a>
</li>
</ul></li>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.handle_modify">handle_modify() (joy.vui.persist_task.PersistTask method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.handle_open">handle_open() (joy.vui.persist_task.PersistTask method)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.handle_persist">handle_persist() (joy.vui.persist_task.PersistTask method)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.handle_persist_new">handle_persist_new() (joy.vui.persist_task.PersistTask method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="I">I</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="main.html#joy.vui.main.init">init() (in module joy.vui.main)</a>
</li>
<li><a href="main.html#joy.vui.main.init_context">init_context() (in module joy.vui.main)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.init_repo">init_repo() (in module joy.vui.persist_task)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.init_text">init_text() (joy.vui.display.Display method)</a>
</li>
<li><a href="core.html#joy.vui.core.TheLoop.install_task">install_task() (joy.vui.core.TheLoop method)</a>
</li>
<li><a href="display.html#joy.vui.display.Display.iter_viewers">iter_viewers() (joy.vui.display.Display method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="J">J</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#module-joy.vui.core">joy.vui.core (module)</a>
</li>
<li><a href="display.html#module-joy.vui.display">joy.vui.display (module)</a>
</li>
<li><a href="main.html#module-joy.vui.main">joy.vui.main (module)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="persist_task.html#module-joy.vui.persist_task">joy.vui.persist_task (module)</a>
</li>
<li><a href="stack_viewer.html#module-joy.vui.stack_viewer">joy.vui.stack_viewer (module)</a>
</li>
<li><a href="text_viewer.html#module-joy.vui.text_viewer">joy.vui.text_viewer (module)</a>
</li>
<li><a href="viewer.html#module-joy.vui.viewer">joy.vui.viewer (module)</a>
</li>
</ul></td>
</tr></table>
<h2 id="L">L</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="main.html#joy.vui.main.load_definitions">load_definitions() (in module joy.vui.main)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="main.html#joy.vui.main.load_primitives">load_primitives() (in module joy.vui.main)</a>
</li>
<li><a href="core.html#joy.vui.core.TheLoop.loop">loop() (joy.vui.core.TheLoop method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="M">M</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="main.html#joy.vui.main.main">main() (in module joy.vui.main)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.make_repo_relative_path_maker">make_repo_relative_path_maker() (in module joy.vui.persist_task)</a>
</li>
<li><a href="viewer.html#joy.vui.viewer.MenuViewer">MenuViewer (class in joy.vui.viewer)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.Message">Message (class in joy.vui.core)</a>
</li>
<li><a href="core.html#joy.vui.core.ModifyMessage">ModifyMessage (class in joy.vui.core)</a>
</li>
<li><a href="core.html#joy.vui.core.MOUSE_EVENTS">MOUSE_EVENTS (in module joy.vui.core)</a>
</li>
</ul></td>
</tr></table>
<h2 id="O">O</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.open">open() (joy.vui.persist_task.PersistTask method)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.open_repo">open_repo() (in module joy.vui.persist_task)</a>
</li>
<li><a href="display.html#joy.vui.display.Display.open_viewer">open_viewer() (joy.vui.display.Display method)</a>
<ul>
<li><a href="display.html#joy.vui.display.Track.open_viewer">(joy.vui.display.Track method)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.open_viewer_on_string">open_viewer_on_string() (in module joy.vui.core)</a>
</li>
<li><a href="core.html#joy.vui.core.OpenMessage">OpenMessage (class in joy.vui.core)</a>
</li>
</ul></td>
</tr></table>
<h2 id="P">P</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.persist">persist() (joy.vui.persist_task.PersistTask method)</a>
<ul>
<li><a href="persist_task.html#joy.vui.persist_task.Resource.persist">(joy.vui.persist_task.Resource method)</a>
</li>
</ul></li>
<li><a href="core.html#joy.vui.core.PersistMessage">PersistMessage (class in joy.vui.core)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask">PersistTask (class in joy.vui.persist_task)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.PickledResource">PickledResource (class in joy.vui.persist_task)</a>
</li>
<li><a href="core.html#joy.vui.core.push">push() (in module joy.vui.core)</a>
</li>
</ul></td>
</tr></table>
<h2 id="R">R</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Display.redraw">redraw() (joy.vui.display.Display method)</a>
<ul>
<li><a href="display.html#joy.vui.display.Track.redraw">(joy.vui.display.Track method)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.TheLoop.remove_task">remove_task() (joy.vui.core.TheLoop method)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.Resource">Resource (class in joy.vui.persist_task)</a>
</li>
<li><a href="core.html#joy.vui.core.TheLoop.run_task">run_task() (joy.vui.core.TheLoop method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="S">S</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.scan">scan() (joy.vui.persist_task.PersistTask method)</a>
</li>
<li><a href="core.html#joy.vui.core.ShutdownMessage">ShutdownMessage (class in joy.vui.core)</a>
</li>
<li><a href="viewer.html#joy.vui.viewer.SomeViewer">SomeViewer (class in joy.vui.viewer)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Track.split">split() (joy.vui.display.Track method)</a>
<ul>
<li><a href="viewer.html#joy.vui.viewer.Viewer.split">(joy.vui.viewer.Viewer method)</a>
</li>
</ul></li>
<li><a href="stack_viewer.html#joy.vui.stack_viewer.StackViewer">StackViewer (class in joy.vui.stack_viewer)</a>
</li>
</ul></td>
</tr></table>
<h2 id="T">T</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.TASK_EVENTS">TASK_EVENTS (in module joy.vui.core)</a>
</li>
<li><a href="persist_task.html#joy.vui.persist_task.PersistTask.task_run">task_run() (joy.vui.persist_task.PersistTask method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="text_viewer.html#joy.vui.text_viewer.TextViewer">TextViewer (class in joy.vui.text_viewer)</a>
</li>
<li><a href="core.html#joy.vui.core.TheLoop">TheLoop (class in joy.vui.core)</a>
</li>
<li><a href="display.html#joy.vui.display.Track">Track (class in joy.vui.display)</a>
</li>
</ul></td>
</tr></table>
<h2 id="V">V</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="viewer.html#joy.vui.viewer.Viewer">Viewer (class in joy.vui.viewer)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="display.html#joy.vui.display.Track.viewer_at">viewer_at() (joy.vui.display.Track method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="W">W</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="core.html#joy.vui.core.World">World (class in joy.vui.core)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="main.html#joy.vui.main.FileFaker.write">write() (joy.vui.main.FileFaker method)</a>
</li>
</ul></td>
</tr></table>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,231 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome to Joy VUIs documentation! &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Core" href="core.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="welcome-to-joy-vui-s-documentation">
<h1>Welcome to Joy VUIs documentation!<a class="headerlink" href="#welcome-to-joy-vui-s-documentation" title="Permalink to this headline"></a></h1>
<p>A simple Graphical User Interface for the Joy programming language,
written using Pygame to bypass X11 et. al., modeled on the Oberon OS, and
intended to be just functional enough to support bootstrapping further Joy
development.</p>
<div class="section" id="screenshot">
<h2>Screenshot<a class="headerlink" href="#screenshot" title="Permalink to this headline"></a></h2>
<img alt="_images/Joy-VUI-screenshot.PNG" src="_images/Joy-VUI-screenshot.PNG" />
</div>
<div class="section" id="quick-start">
<h2>Quick Start<a class="headerlink" href="#quick-start" title="Permalink to this headline"></a></h2>
<p>If you have PyGame and Dulwich installed you should be able to start the
VUI with the following command:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">joy</span><span class="o">.</span><span class="n">vui</span>
</pre></div>
</div>
<p>This will create a <code class="docutils literal notranslate"><span class="pre">~/.thun</span></code> directory in your home dir to store your
data.</p>
</div>
<div class="section" id="how-it-works-now">
<h2>How it works now.<a class="headerlink" href="#how-it-works-now" title="Permalink to this headline"></a></h2>
<p>The VUI is more-or-less a crude text editor along with
a simple Joy runtime (interpreter, stack, and dictionary.) It auto-saves
any named files (in a versioned home directory) and you can write new Joy
primitives in Python and Joy definitions and immediately install and use
them, as well as recording them for reuse (after restarts.)</p>
<p>The only dependencies are Pygame and Dulwich (a Python Git library.)</p>
<p>When the main.py script starts it checks for an environment var “JOY_HOME”
which should point to a directory where you want the system to store the
files (“resources”) it will edit and save, this directory defaults to
<code class="docutils literal notranslate"><span class="pre">~/.thun</span></code>. The first time you run it, it will create some default files
as content. Right click on see_resources to open a viewer with the list
of resources (files), copy a name to the stack and right click on
open_resource_at_good_location to open a viewer on that resource.</p>
<p>Right now the screen size defaults to windowed 1024x768, but if you pass
the <code class="docutils literal notranslate"><span class="pre">-f</span></code> option to the main.py script the UI will take up the full screen
at the highest available resolution. The window is divided into two (or
three in fullscreen) vertical “tracks”, and the number and width of the
tracks are fixed at start up. (Feel free to edit the values in main.py to
play around with different track configurations.) Each track gets divided
horizontally into zero or more “viewers” (like windows in a windowed GUI,
cf. Chapter 4 of “Project Oberon”) for a kind of tiled layout.</p>
<p>Currently, there are only two kinds of (interesting) viewers: TextViewers
and StackViewer. The TextViewers are crude text editors. They provide
just enough functionality to let the user write text and code (Python and
Joy) and execute Joy functions. One important thing they do is
automatically save their content after changes. No more lost work.</p>
<p>The StackViewer is a specialized TextViewer that shows the contents of the
Joy stack one line per stack item. Its a very handy visual aid to keep
track of whats going on. Theres also a log.txt file that gets written
to when commands are executed, and so records the log of user actions and
system events. It tends to fill up quickly so theres a reset_log command
that clears it out.</p>
<p>Viewers have “grow” and “close” in their menu bars. These are buttons.
When you right-click on grow a viewer a copy is created that covers that
viewers entire track. If you grow a viewer that already takes up its
whole track then a copy is created that takes up an additional track, up
to the whole screen. Closing a viewer just deletes that viewer, and when
a track has no more viewers, it is deleted and that exposes any previous
tracks and viewers that were hidden.</p>
<p>(Note: if you ever close all the viewers and are sitting at a blank screen
with nowhere to type and execute commands, press the Pause/Break key.
This will open a new “trap” viewer which you can then use to recover.)</p>
<p>Copies of a viewer all share the same model and update their display as it
changes. (If you have two viewers open on the same named resource and edit
one youll see the other update as you type.)</p>
</div>
<div class="section" id="ui-guide">
<h2>UI Guide<a class="headerlink" href="#ui-guide" title="Permalink to this headline"></a></h2>
<p>left mouse sets cursor in text, in menu bar resizes viewer interactively
(this is a little buggy in that you can move the mouse quickly and get
outside the menu, leaving the viewer in the “resizing” state. Until I fix
this, the workaround is to just grab the menu bar again and wiggle it a
few pixels and let go. This will reset the machinery.)</p>
<p>Right mouse executes Joy command (functions), and you can drag with the
right button to highlight (well, underline) commands. Words that arent
names of Joy commands wont be underlined. Release the button to execute
the command.</p>
<p>The middle mouse button (usually a wheel these days) scrolls the text but
you can also click and drag any viewer with it to move that viewer to
another track or to a different location in the same track. Theres no
direct visual feedback for this (yet) but that dosent seem to impair its
usefulness.</p>
<p>F1, F2 - set selection begin and end markers (crude but usable.)</p>
<p>F3 - copy selected text to the top of the stack.</p>
<p>Shift-F3 - as copy then run “parse” command on the string.</p>
<p>F4 - cut selected text to the top of the stack.</p>
<p>Shift-F4 - as cut then run “pop” (delete selection.)</p>
</div>
<div class="section" id="joy">
<h2>Joy<a class="headerlink" href="#joy" title="Permalink to this headline"></a></h2>
<p>Pretty much all of the rest of the functionality of the system is provided
by executing Joy commands (aka functions, aka “words” in Forth) by right-
clicking on their names in any text.</p>
<p>To get help on a Joy function select the name of the function in a
TextViewer using F1 and F2, then press shift-F3 to parse the selection.
The function (really its Symbol) will appear on the stack in brackets (a
“quoted program” such as “[pop]”.) Then right-click on the word help in
any TextViewer (if its not already there, just type it in somewhere.)
This will print the docstring or definition of the word (function) to
stdout. At some point Ill write a thing to send that to the log.txt file
instead, but for now look for output in the terminal.</p>
</div>
<div class="section" id="modules">
<h2>Modules<a class="headerlink" href="#modules" title="Permalink to this headline"></a></h2>
<img alt="_images/packages_Vui.png" src="_images/packages_Vui.png" />
<div class="toctree-wrapper compound">
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
</div>
</div>
<div class="section" id="indices-and-tables">
<h2>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></li>
<li><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></li>
<li><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="#">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="#">Documentation overview</a><ul>
<li>Next: <a href="core.html" title="next chapter">Core</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/index.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@ -0,0 +1,180 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Main Module &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Display" href="display.html" />
<link rel="prev" title="Core" href="core.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<span class="target" id="module-joy.vui.main"></span><div class="section" id="main-module">
<h1>Main Module<a class="headerlink" href="#main-module" title="Permalink to this headline"></a></h1>
<p>Pulls everything together.</p>
<dl class="class">
<dt id="joy.vui.main.FileFaker">
<em class="property">class </em><code class="descclassname">joy.vui.main.</code><code class="descname">FileFaker</code><span class="sig-paren">(</span><em>log</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#FileFaker"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.FileFaker" title="Permalink to this definition"></a></dt>
<dd><p>Pretends to be a file object but writes to log instead.</p>
<dl class="method">
<dt id="joy.vui.main.FileFaker.write">
<code class="descname">write</code><span class="sig-paren">(</span><em>text</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#FileFaker.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.FileFaker.write" title="Permalink to this definition"></a></dt>
<dd><p>Write text to log.</p>
</dd></dl>
</dd></dl>
<dl class="function">
<dt id="joy.vui.main.error_guard">
<code class="descclassname">joy.vui.main.</code><code class="descname">error_guard</code><span class="sig-paren">(</span><em>loop</em>, <em>n=10</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#error_guard"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.error_guard" title="Permalink to this definition"></a></dt>
<dd><p>Run a loop function, retry for <code class="docutils literal notranslate"><span class="pre">n</span></code> exceptions.
Prints tracebacks on <code class="docutils literal notranslate"><span class="pre">sys.stderr</span></code>.</p>
</dd></dl>
<dl class="function">
<dt id="joy.vui.main.init">
<code class="descclassname">joy.vui.main.</code><code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#init"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.init" title="Permalink to this definition"></a></dt>
<dd><p>Initialize the system.</p>
<ul class="simple">
<li>Init PyGame</li>
<li>Create main window</li>
<li>Start the PyGame clock</li>
<li>Set the event mask</li>
<li>Create the PersistTask</li>
</ul>
</dd></dl>
<dl class="function">
<dt id="joy.vui.main.init_context">
<code class="descclassname">joy.vui.main.</code><code class="descname">init_context</code><span class="sig-paren">(</span><em>screen</em>, <em>clock</em>, <em>pt</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#init_context"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.init_context" title="Permalink to this definition"></a></dt>
<dd><p>More initialization</p>
<ul class="simple">
<li>Create the Joy dictionary</li>
<li>Create the Display</li>
<li>Open the log, menu, and scratch text viewers, and the stack pickle</li>
<li>Start the main loop</li>
<li>Create the World object</li>
<li>Register PersistTask and World message handlers with the Display</li>
<li>Load user function definitions.</li>
</ul>
</dd></dl>
<dl class="function">
<dt id="joy.vui.main.load_definitions">
<code class="descclassname">joy.vui.main.</code><code class="descname">load_definitions</code><span class="sig-paren">(</span><em>pt</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#load_definitions"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.load_definitions" title="Permalink to this definition"></a></dt>
<dd><p>Load definitions from <code class="docutils literal notranslate"><span class="pre">definitions.txt</span></code>.</p>
</dd></dl>
<dl class="function">
<dt id="joy.vui.main.load_primitives">
<code class="descclassname">joy.vui.main.</code><code class="descname">load_primitives</code><span class="sig-paren">(</span><em>home</em>, <em>name_space</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#load_primitives"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.load_primitives" title="Permalink to this definition"></a></dt>
<dd><p>Load primitives from <code class="docutils literal notranslate"><span class="pre">library.py</span></code>.</p>
</dd></dl>
<dl class="function">
<dt id="joy.vui.main.main">
<code class="descclassname">joy.vui.main.</code><code class="descname">main</code><span class="sig-paren">(</span><em>screen</em>, <em>clock</em>, <em>pt</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/main.html#main"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.main.main" title="Permalink to this definition"></a></dt>
<dd><p>Main function.</p>
<ul class="simple">
<li>Call <code class="docutils literal notranslate"><span class="pre">init_context()</span></code></li>
<li>Load primitives</li>
<li>Create an <code class="docutils literal notranslate"><span class="pre">evaluate</span></code> function that lets you just eval some Python code</li>
<li>Redirect <code class="docutils literal notranslate"><span class="pre">stdout</span></code> to the log using a <code class="docutils literal notranslate"><span class="pre">FileFaker</span></code> object, and…</li>
<li>Start the main loop.</li>
</ul>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="core.html" title="previous chapter">Core</a></li>
<li>Next: <a href="display.html" title="next chapter">Display</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/main.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

Binary file not shown.

View File

@ -0,0 +1,222 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Persist Task &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="prev" title="Stack Viewer" href="stack_viewer.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<span class="target" id="module-joy.vui.persist_task"></span><div class="section" id="persist-task">
<h1>Persist Task<a class="headerlink" href="#persist-task" title="Permalink to this headline"></a></h1>
<p>This module deals with persisting the “resources” (text files and the
stack) to the git repo in the <code class="docutils literal notranslate"><span class="pre">JOY_HOME</span></code> directory.</p>
<dl class="class">
<dt id="joy.vui.persist_task.PersistTask">
<em class="property">class </em><code class="descclassname">joy.vui.persist_task.</code><code class="descname">PersistTask</code><span class="sig-paren">(</span><em>home</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask" title="Permalink to this definition"></a></dt>
<dd><p>This class deals with saving changes to the git repo.</p>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.commit">
<code class="descname">commit</code><span class="sig-paren">(</span><em>message='auto-commit'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.commit"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.commit" title="Permalink to this definition"></a></dt>
<dd><p>Commit.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.handle">
<code class="descname">handle</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.handle"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.handle" title="Permalink to this definition"></a></dt>
<dd><p>Handle messages, dispatch to <code class="docutils literal notranslate"><span class="pre">handle_FOO()</span></code> methods.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.handle_modify">
<code class="descname">handle_modify</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.handle_modify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.handle_modify" title="Permalink to this definition"></a></dt>
<dd><p>Foo.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.handle_open">
<code class="descname">handle_open</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.handle_open"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.handle_open" title="Permalink to this definition"></a></dt>
<dd><p>Foo.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.handle_persist">
<code class="descname">handle_persist</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.handle_persist"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.handle_persist" title="Permalink to this definition"></a></dt>
<dd><p>Foo.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.handle_persist_new">
<code class="descname">handle_persist_new</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.handle_persist_new"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.handle_persist_new" title="Permalink to this definition"></a></dt>
<dd><p>Foo.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.open">
<code class="descname">open</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.open"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.open" title="Permalink to this definition"></a></dt>
<dd><p>Look up the named file in home and return its content_id and data.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.persist">
<code class="descname">persist</code><span class="sig-paren">(</span><em>content_id</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.persist"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.persist" title="Permalink to this definition"></a></dt>
<dd><p>Persist a resource.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.scan">
<code class="descname">scan</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.scan"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.scan" title="Permalink to this definition"></a></dt>
<dd><p>Return a sorted list of all the files in the home dir.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.persist_task.PersistTask.task_run">
<code class="descname">task_run</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PersistTask.task_run"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PersistTask.task_run" title="Permalink to this definition"></a></dt>
<dd><p>Stage any outstanding changes.</p>
</dd></dl>
</dd></dl>
<dl class="class">
<dt id="joy.vui.persist_task.PickledResource">
<em class="property">class </em><code class="descclassname">joy.vui.persist_task.</code><code class="descname">PickledResource</code><span class="sig-paren">(</span><em>filename</em>, <em>repo_relative_filename</em>, <em>thing=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#PickledResource"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.PickledResource" title="Permalink to this definition"></a></dt>
<dd><p>A <code class="docutils literal notranslate"><span class="pre">Resource</span></code> subclass that uses <code class="docutils literal notranslate"><span class="pre">pickle</span></code> on its file/thing.</p>
</dd></dl>
<dl class="class">
<dt id="joy.vui.persist_task.Resource">
<em class="property">class </em><code class="descclassname">joy.vui.persist_task.</code><code class="descname">Resource</code><span class="sig-paren">(</span><em>filename</em>, <em>repo_relative_filename</em>, <em>thing=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#Resource"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.Resource" title="Permalink to this definition"></a></dt>
<dd><p>Handle the content of a text files as a list of lines, deal with
saving it and staging the changes to a repo.</p>
<dl class="method">
<dt id="joy.vui.persist_task.Resource.persist">
<code class="descname">persist</code><span class="sig-paren">(</span><em>repo</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#Resource.persist"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.Resource.persist" title="Permalink to this definition"></a></dt>
<dd><p>Save the lines to the file and stage the file in the repo.</p>
</dd></dl>
</dd></dl>
<dl class="function">
<dt id="joy.vui.persist_task.check_filename">
<code class="descclassname">joy.vui.persist_task.</code><code class="descname">check_filename</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#check_filename"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.check_filename" title="Permalink to this definition"></a></dt>
<dd><p>Sanity checks for filename.</p>
</dd></dl>
<dl class="function">
<dt id="joy.vui.persist_task.init_repo">
<code class="descclassname">joy.vui.persist_task.</code><code class="descname">init_repo</code><span class="sig-paren">(</span><em>repo_dir</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#init_repo"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.init_repo" title="Permalink to this definition"></a></dt>
<dd><p>Initialize a git repository in the directory. Stage and commit all
files (toplevel, not those in subdirectories if any) in the dir.</p>
</dd></dl>
<dl class="function">
<dt id="joy.vui.persist_task.make_repo_relative_path_maker">
<code class="descclassname">joy.vui.persist_task.</code><code class="descname">make_repo_relative_path_maker</code><span class="sig-paren">(</span><em>repo</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#make_repo_relative_path_maker"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.make_repo_relative_path_maker" title="Permalink to this definition"></a></dt>
<dd><p>Helper function to return a function that returns a path given a path,
thats relative to the repository.</p>
</dd></dl>
<dl class="function">
<dt id="joy.vui.persist_task.open_repo">
<code class="descclassname">joy.vui.persist_task.</code><code class="descname">open_repo</code><span class="sig-paren">(</span><em>repo_dir=None</em>, <em>initialize=False</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/persist_task.html#open_repo"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.persist_task.open_repo" title="Permalink to this definition"></a></dt>
<dd><p>Open, or create, and return a Dulwich git repo object for the given
directory. If the dir path doesnt exist it will be created. If it
does exist but isnt a repo the result depends on the <code class="docutils literal notranslate"><span class="pre">initialize</span></code>
argument. If it is <code class="docutils literal notranslate"><span class="pre">False</span></code> (the default) a <code class="docutils literal notranslate"><span class="pre">NotGitRepository</span></code>
exception is raised, otherwise <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">init</span></code> is effected in the dir.</p>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="stack_viewer.html" title="previous chapter">Stack Viewer</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/persist_task.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@ -0,0 +1,153 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Python Module Index &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Python Module Index</h1>
<div class="modindex-jumpbox">
<a href="#cap-j"><strong>j</strong></a>
</div>
<table class="indextable modindextable">
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-j"><td></td><td>
<strong>j</strong></td><td></td></tr>
<tr>
<td><img src="_static/minus.png" class="toggler"
id="toggle-1" style="display: none" alt="-" /></td>
<td>
<code class="xref">joy</code></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="core.html#module-joy.vui.core"><code class="xref">joy.vui.core</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="display.html#module-joy.vui.display"><code class="xref">joy.vui.display</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="main.html#module-joy.vui.main"><code class="xref">joy.vui.main</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="persist_task.html#module-joy.vui.persist_task"><code class="xref">joy.vui.persist_task</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="stack_viewer.html#module-joy.vui.stack_viewer"><code class="xref">joy.vui.stack_viewer</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="text_viewer.html#module-joy.vui.text_viewer"><code class="xref">joy.vui.text_viewer</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="viewer.html#module-joy.vui.viewer"><code class="xref">joy.vui.viewer</code></a></td><td>
<em></em></td></tr>
</table>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

View File

@ -0,0 +1,116 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
<script type="text/javascript" id="searchindexloader"></script>
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="main.html">Main Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,114 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Stack Viewer &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="prev" title="Text Viewer" href="text_viewer.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<span class="target" id="module-joy.vui.stack_viewer"></span><div class="section" id="stack-viewer">
<h1>Stack Viewer<a class="headerlink" href="#stack-viewer" title="Permalink to this headline"></a></h1>
<dl class="class">
<dt id="joy.vui.stack_viewer.StackViewer">
<em class="property">class </em><code class="descclassname">joy.vui.stack_viewer.</code><code class="descname">StackViewer</code><span class="sig-paren">(</span><em>surface</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/stack_viewer.html#StackViewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.stack_viewer.StackViewer" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="joy.vui.stack_viewer.fsi">
<code class="descclassname">joy.vui.stack_viewer.</code><code class="descname">fsi</code><span class="sig-paren">(</span><em>item</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/stack_viewer.html#fsi"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.stack_viewer.fsi" title="Permalink to this definition"></a></dt>
<dd><p>Format Stack Item</p>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Stack Viewer</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="text_viewer.html" title="previous chapter">Text Viewer</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/stack_viewer.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@ -0,0 +1,124 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Text Viewer &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Stack Viewer" href="stack_viewer.html" />
<link rel="prev" title="Viewer" href="viewer.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<span class="target" id="module-joy.vui.text_viewer"></span><div class="section" id="text-viewer">
<h1>Text Viewer<a class="headerlink" href="#text-viewer" title="Permalink to this headline"></a></h1>
<dl class="class">
<dt id="joy.vui.text_viewer.TextViewer">
<em class="property">class </em><code class="descclassname">joy.vui.text_viewer.</code><code class="descname">TextViewer</code><span class="sig-paren">(</span><em>surface</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/text_viewer.html#TextViewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.text_viewer.TextViewer" title="Permalink to this definition"></a></dt>
<dd><dl class="method">
<dt id="joy.vui.text_viewer.TextViewer.at">
<code class="descname">at</code><span class="sig-paren">(</span><em>x</em>, <em>y</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/text_viewer.html#TextViewer.at"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.text_viewer.TextViewer.at" title="Permalink to this definition"></a></dt>
<dd><p>Given screen coordinates return the line, row, and column of the
character there.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.text_viewer.TextViewer.close">
<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/text_viewer.html#TextViewer.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.text_viewer.TextViewer.close" title="Permalink to this definition"></a></dt>
<dd><p>Close the viewer and release any resources, etc…</p>
</dd></dl>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1"><a class="reference internal" href="viewer.html">Viewer</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="persist_task.html">Persist Task</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="viewer.html" title="previous chapter">Viewer</a></li>
<li>Next: <a href="stack_viewer.html" title="next chapter">Stack Viewer</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/text_viewer.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@ -0,0 +1,150 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Viewer &#8212; Joy VUI 0.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Text Viewer" href="text_viewer.html" />
<link rel="prev" title="Display" href="display.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<span class="target" id="module-joy.vui.viewer"></span><div class="section" id="viewer">
<h1>Viewer<a class="headerlink" href="#viewer" title="Permalink to this headline"></a></h1>
<dl class="class">
<dt id="joy.vui.viewer.MenuViewer">
<em class="property">class </em><code class="descclassname">joy.vui.viewer.</code><code class="descname">MenuViewer</code><span class="sig-paren">(</span><em>surface</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/viewer.html#MenuViewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.viewer.MenuViewer" title="Permalink to this definition"></a></dt>
<dd><p>MenuViewer class</p>
<dl class="method">
<dt id="joy.vui.viewer.MenuViewer.draw">
<code class="descname">draw</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/viewer.html#MenuViewer.draw"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.viewer.MenuViewer.draw" title="Permalink to this definition"></a></dt>
<dd><p>Draw the viewer onto its surface.</p>
</dd></dl>
</dd></dl>
<dl class="class">
<dt id="joy.vui.viewer.SomeViewer">
<em class="property">class </em><code class="descclassname">joy.vui.viewer.</code><code class="descname">SomeViewer</code><span class="sig-paren">(</span><em>surface</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/viewer.html#SomeViewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.viewer.SomeViewer" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="class">
<dt id="joy.vui.viewer.Viewer">
<em class="property">class </em><code class="descclassname">joy.vui.viewer.</code><code class="descname">Viewer</code><span class="sig-paren">(</span><em>surface</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/viewer.html#Viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.viewer.Viewer" title="Permalink to this definition"></a></dt>
<dd><p>Base Viewer class</p>
<dl class="method">
<dt id="joy.vui.viewer.Viewer.close">
<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/viewer.html#Viewer.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.viewer.Viewer.close" title="Permalink to this definition"></a></dt>
<dd><p>Close the viewer and release any resources, etc…</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.viewer.Viewer.draw">
<code class="descname">draw</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/viewer.html#Viewer.draw"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.viewer.Viewer.draw" title="Permalink to this definition"></a></dt>
<dd><p>Draw the viewer onto its surface.</p>
</dd></dl>
<dl class="method">
<dt id="joy.vui.viewer.Viewer.split">
<code class="descname">split</code><span class="sig-paren">(</span><em>y</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/vui/viewer.html#Viewer.split"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.vui.viewer.Viewer.split" title="Permalink to this definition"></a></dt>
<dd><p>Split the viewer at the y coordinate (which is relative to the
viewers surface and must be inside it somewhere) and return the
remaining height. The upper part of the viewer remains (and gets
redrawn on a new surface) and the lower space is now available
for e.g. a new viewer.</p>
</dd></dl>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Joy VUI</a></h1>
<h3>Navigation</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="core.html">Core</a></li>
<li class="toctree-l1"><a class="reference internal" href="display.html">Display</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="text_viewer.html">Text Viewer</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack_viewer.html">Stack Viewer</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="display.html" title="previous chapter">Display</a></li>
<li>Next: <a href="text_viewer.html" title="next chapter">Text Viewer</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2019, Simon Forman.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
|
<a href="_sources/viewer.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@ -0,0 +1,3 @@
.. automodule:: joy.vui.main
:members:

View File

@ -22,6 +22,9 @@
Persist Task Persist Task
=========================== ===========================
This module deals with persisting the "resources" (text files and the
stack) to the git repo in the ``JOY_HOME`` directory.
''' '''
import os, pickle, traceback import os, pickle, traceback
from collections import Counter from collections import Counter
@ -31,6 +34,13 @@ from joy.vui import core, init_joy_home
def open_repo(repo_dir=None, initialize=False): def open_repo(repo_dir=None, initialize=False):
'''
Open, or create, and return a Dulwich git repo object for the given
directory. If the dir path doesn't exist it will be created. If it
does exist but isn't a repo the result depends on the ``initialize``
argument. If it is ``False`` (the default) a ``NotGitRepository``
exception is raised, otherwise ``git init`` is effected in the dir.
'''
if not os.path.exists(repo_dir): if not os.path.exists(repo_dir):
os.makedirs(repo_dir, 0700) os.makedirs(repo_dir, 0700)
return init_repo(repo_dir) return init_repo(repo_dir)
@ -43,6 +53,10 @@ def open_repo(repo_dir=None, initialize=False):
def init_repo(repo_dir): def init_repo(repo_dir):
'''
Initialize a git repository in the directory. Stage and commit all
files (toplevel, not those in subdirectories if any) in the dir.
'''
repo = Repo.init(repo_dir) repo = Repo.init(repo_dir)
init_joy_home.initialize(repo_dir) init_joy_home.initialize(repo_dir)
repo.stage([ repo.stage([
@ -55,6 +69,10 @@ def init_repo(repo_dir):
def make_repo_relative_path_maker(repo): def make_repo_relative_path_maker(repo):
'''
Helper function to return a function that returns a path given a path,
that's relative to the repository.
'''
c = repo.controldir() c = repo.controldir()
def repo_relative_path(path): def repo_relative_path(path):
return os.path.relpath(path, os.path.commonprefix((c, path))) return os.path.relpath(path, os.path.commonprefix((c, path)))
@ -62,6 +80,10 @@ def make_repo_relative_path_maker(repo):
class Resource(object): class Resource(object):
'''
Handle the content of a text files as a list of lines, deal with
saving it and staging the changes to a repo.
'''
def __init__(self, filename, repo_relative_filename, thing=None): def __init__(self, filename, repo_relative_filename, thing=None):
self.filename = filename self.filename = filename
@ -76,6 +98,9 @@ class Resource(object):
print >> f, line print >> f, line
def persist(self, repo): def persist(self, repo):
'''
Save the lines to the file and stage the file in the repo.
'''
with open(self.filename, 'w') as f: with open(self.filename, 'w') as f:
os.chmod(self.filename, 0600) os.chmod(self.filename, 0600)
self._to_file(f) self._to_file(f)
@ -86,6 +111,9 @@ class Resource(object):
class PickledResource(Resource): class PickledResource(Resource):
'''
A ``Resource`` subclass that uses ``pickle`` on its file/thing.
'''
def _from_file(self, f): def _from_file(self, f):
return [pickle.load(f)] return [pickle.load(f)]
@ -95,6 +123,9 @@ class PickledResource(Resource):
class PersistTask(object): class PersistTask(object):
'''
This class deals with saving changes to the git repo.
'''
LIMIT = 10 LIMIT = 10
MAX_SAVE = 10 MAX_SAVE = 10
@ -107,7 +138,9 @@ class PersistTask(object):
self.store = {} self.store = {}
def open(self, name): def open(self, name):
# look up the file in home and get its data '''
Look up the named file in home and return its content_id and data.
'''
fn = os.path.join(self.home, name) fn = os.path.join(self.home, name)
content_id = name # hash(fn) content_id = name # hash(fn)
try: try:
@ -118,6 +151,9 @@ class PersistTask(object):
return content_id, resource.thing return content_id, resource.thing
def handle(self, message): def handle(self, message):
'''
Handle messages, dispatch to ``handle_FOO()`` methods.
'''
if isinstance(message, core.OpenMessage): if isinstance(message, core.OpenMessage):
self.handle_open(message) self.handle_open(message)
elif isinstance(message, core.ModifyMessage): elif isinstance(message, core.ModifyMessage):
@ -130,6 +166,9 @@ class PersistTask(object):
self.commit('shutdown') self.commit('shutdown')
def handle_open(self, message): def handle_open(self, message):
'''
Foo.
'''
try: try:
message.content_id, message.thing = self.open(message.name) message.content_id, message.thing = self.open(message.name)
except: except:
@ -139,6 +178,9 @@ class PersistTask(object):
message.status = core.SUCCESS message.status = core.SUCCESS
def handle_modify(self, message): def handle_modify(self, message):
'''
Foo.
'''
try: try:
content_id = message.details['content_id'] content_id = message.details['content_id']
except KeyError: except KeyError:
@ -151,6 +193,9 @@ class PersistTask(object):
self.commit('due to activity') self.commit('due to activity')
def handle_persist(self, message): def handle_persist(self, message):
'''
Foo.
'''
try: try:
resource = self.store[message.content_id] resource = self.store[message.content_id]
except KeyError: except KeyError:
@ -159,6 +204,9 @@ class PersistTask(object):
self.commit('by request from %r' % (message.sender,)) self.commit('by request from %r' % (message.sender,))
def handle_persist_new(self, message): def handle_persist_new(self, message):
'''
Foo.
'''
name = message.content_id name = message.content_id
check_filename(name) check_filename(name)
fn = os.path.join(self.home, name) fn = os.path.join(self.home, name)
@ -168,10 +216,16 @@ class PersistTask(object):
return resource return resource
def persist(self, content_id): def persist(self, content_id):
'''
Persist a resource.
'''
del self.counter[content_id] del self.counter[content_id]
self.store[content_id].persist(self.repo) self.store[content_id].persist(self.repo)
def task_run(self): def task_run(self):
'''
Stage any outstanding changes.
'''
if not self.counter: if not self.counter:
return return
for content_id, _ in self.counter.most_common(self.MAX_SAVE): for content_id, _ in self.counter.most_common(self.MAX_SAVE):
@ -179,9 +233,15 @@ class PersistTask(object):
self.commit() self.commit()
def commit(self, message='auto-commit'): def commit(self, message='auto-commit'):
'''
Commit.
'''
return self.repo.do_commit(message, committer=core.COMMITTER) return self.repo.do_commit(message, committer=core.COMMITTER)
def scan(self): def scan(self):
'''
Return a sorted list of all the files in the home dir.
'''
return sorted([ return sorted([
fn fn
for fn in os.listdir(self.home) for fn in os.listdir(self.home)
@ -190,6 +250,9 @@ class PersistTask(object):
def check_filename(name): def check_filename(name):
'''
Sanity checks for filename.
'''
# TODO: improve this... # TODO: improve this...
if len(name) > 64: if len(name) > 64:
raise ValueError('bad name %r' % (name,)) raise ValueError('bad name %r' % (name,))
@ -198,7 +261,6 @@ def check_filename(name):
raise ValueError('bad name %r' % (name,)) raise ValueError('bad name %r' % (name,))
if __name__ == '__main__': if __name__ == '__main__':
JOY_HOME = os.path.expanduser('~/.thun') JOY_HOME = os.path.expanduser('~/.thun')
pt = PersistTask(JOY_HOME) pt = PersistTask(JOY_HOME)