docs: add NetRadiant specific docs
310
docs/Additional_map_compiler_features.htm
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
<!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" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>NetRadiant - Additional map compiler features - Alientrap Development</title>
|
||||
<meta name="description" content="Redmine" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<link href="application.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<script src="prototype.js" type="text/javascript"></script>
|
||||
<script src="effects.js" type="text/javascript"></script>
|
||||
<script src="dragdrop.js" type="text/javascript"></script>
|
||||
<script src="controls.js" type="text/javascript"></script>
|
||||
<script src="application.js" type="text/javascript"></script>
|
||||
<link href="jstoolbar.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!--[if IE]>
|
||||
<style type="text/css">
|
||||
* html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
|
||||
body {behavior: url(/stylesheets/csshover.htc?1267352889);}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
.question { background-color:#FFEBC1; border:2px solid #FDBD3B; margin-bottom:12px; padding:0px 4px 8px 4px; }
|
||||
td.formatted_questions { text-align: left; white-space: normal}
|
||||
td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
|
||||
</style>
|
||||
<link href="stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!-- page specific tags -->
|
||||
|
||||
<link href="scm.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="top-menu">
|
||||
<div id="account">
|
||||
<ul><li><a href="/login" class="login">Войти</a></li>
|
||||
<li><a href="/account/register" class="register">Регистрация</a></li></ul> </div>
|
||||
|
||||
<ul><li><a href="/" class="home">Домашняя страница</a></li>
|
||||
<li><a href="/projects" class="projects">Проекты</a></li>
|
||||
<li><a href="http://www.redmine.org/guide" class="help">Помощь</a></li></ul></div>
|
||||
|
||||
<div id="header">
|
||||
<div id="quick-search">
|
||||
<form action="/search/index/netradiant" method="get">
|
||||
<input name="wiki_pages" type="hidden" value="1" />
|
||||
<a href="/search/index/netradiant" accesskey="4">Поиск</a>:
|
||||
<input accesskey="f" class="small" id="q" name="q" size="20" type="text" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<h1>NetRadiant</h1>
|
||||
|
||||
<div id="main-menu">
|
||||
<ul><li><a href="/projects/netradiant" class="overview">Просмотр</a></li>
|
||||
<li><a href="/projects/netradiant/activity" class="activity">Активность</a></li>
|
||||
<li><a href="/projects/netradiant/issues" class="issues">Задачи</a></li>
|
||||
<li><a href="/projects/netradiant/news" class="news">Новости</a></li>
|
||||
<li><a href="/projects/netradiant/documents" class="documents">Документы</a></li>
|
||||
<li><a href="/projects/netradiant/wiki" class="wiki selected">Wiki</a></li>
|
||||
<li><a href="/projects/netradiant/boards" class="boards">Форумы</a></li>
|
||||
<li><a href="/projects/netradiant/files" class="files">Файлы</a></li>
|
||||
<li><a href="/projects/netradiant/repository" class="repository">Хранилище</a></li>
|
||||
<li><a href="/ezfaq/index/netradiant" class="ezfaq">FAQ</a></li></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="" id="main">
|
||||
<div id="sidebar">
|
||||
|
||||
<h3>Wiki</h3>
|
||||
|
||||
<a href="/projects/netradiant/wiki">Стартовая страница</a><br />
|
||||
<a href="/projects/netradiant/wiki/Page_index">Оглавление</a><br />
|
||||
<a href="/projects/netradiant/wiki/Date_index">История страниц</a><br />
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div class="contextual">
|
||||
|
||||
|
||||
<span id="watcher"></span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/projects/netradiant/wiki/Additional_map_compiler_features/history" class="icon icon-history">История</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="wiki">
|
||||
<h1 id="Additional-map-compiler-features">Additional map compiler features<a href="#Additional-map-compiler-features" class="wiki-anchor">¶</a></h1>
|
||||
|
||||
|
||||
<p>The following features for use by mappers have been added in NetRadiant and thus are not documented elsewhere:</p>
|
||||
|
||||
<h2 id="Floodlighting">Floodlighting<a href="#Floodlighting" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p><div style="float:right"><img src="floodlight.jpg" alt="" /></div></p>
|
||||
|
||||
|
||||
<p>A very quick and dirty way to light a map is adding the following key to <code>worldspawn</code>:</p>
|
||||
|
||||
|
||||
<pre>
|
||||
"_floodlight" "240 240 255 1024 128"
|
||||
</pre><br />The parameters work as follow: the first three numbers select the color of the lighting. The fourth number sets a distance to trace, and the last number sets the intensity of the floodlight.
|
||||
|
||||
<p>This lighting is somewhat similar to <code>-dirty</code>, combined with use of the <code>ambient</code> key in <code>worldspawn</code>.</p>
|
||||
|
||||
|
||||
<p>This feature was contributed by the Urban Terror team.</p>
|
||||
|
||||
|
||||
<h2 id="Lightmap-exposure">Lightmap exposure<a href="#Lightmap-exposure" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p><div style="float:right"><img src="exposure.jpg" alt="" /></div></p>
|
||||
|
||||
|
||||
<p>The q3map2 light compile parameter <code>-exposure</code> changes the handling of overbright pixels to look more realistic. Try values like <code>-exposure 200</code>! The higher the value, the darker the result gets.</p>
|
||||
|
||||
|
||||
<p>It is most interesting if you intentionally put colored lights of a far too high light value in your map.</p>
|
||||
|
||||
|
||||
<p>This feature was contributed by the Urban Terror team.</p>
|
||||
|
||||
|
||||
<h2 class="clearbefore" id="dotProductScale">dotProductScale<a href="#dotProductScale" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> <img src="dotproduct-small.jpg" alt="" /> </td>
|
||||
<td> <img src="/attachments/download/15" alt="" /> </td>
|
||||
<td> <img src="/attachments/download/16" alt="" /> </td>
|
||||
<td> <img src="/attachments/download/17" alt="" /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> dotProduct </td>
|
||||
<td> dotProduct2 </td>
|
||||
<td> dotProductScale </td>
|
||||
<td> dotProduct2scale </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>The following shader parameters are added for use with terrain blending:</p>
|
||||
|
||||
|
||||
<pre>
|
||||
q3map_alphagen dotProduct2scale ( X Y Z MIN MAX )
|
||||
</pre>
|
||||
|
||||
<p>As with <code>dotProduct2</code>, <code>X Y Z</code> denote the normal on the plane to use for dotProduct terrain blending. The values <code>MIN</code> and <code>MAX</code> specify a range of squared cosine values, so that <code>MIN</code> is mapped to alpha value 0, <code>MAX</code> is mapped to alpha value 1, and everything in between is mapped linearily.</p>
|
||||
|
||||
|
||||
<p>If you prefer working with angles, you can set <code>MIN</code> to the squared cosine of the most steep angle of the blending, and <code>MAX</code> to the squared cosine of the most flat angle of the blending. Example:</p>
|
||||
|
||||
|
||||
<pre>
|
||||
q3map_alphagen dotProduct2scale ( 0 0 1 0.250 0.933 )
|
||||
</pre>
|
||||
|
||||
<p>will set alpha value 0 for anything steeper than 60 degrees, and alpha value 1 for anything more flat than 15 degrees.</p>
|
||||
|
||||
|
||||
<p>The same extension to <code>dotProduct</code> is called <code>dotProductScale</code>. Note that the <code>MIN</code> and <code>MAX</code> values are not squared there. You get a different curve with the same min/max angles by writing:</p>
|
||||
|
||||
|
||||
<pre>
|
||||
q3map_alphagen dotProductScale ( 0 0 1 0.500 0.966 )
|
||||
</pre>
|
||||
|
||||
<h2 id="Minimum-sample-size">Minimum sample size<a href="#Minimum-sample-size" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>The compiler option <code>-minsamplesize</code> in the BSP stage enforces a given minimum<br />sample size, even if shaders or <code>func_groups</code> set a lightmap scale. This allows<br />higher quality compiles of existing maps that use these features without having<br />to create extraordinarily large amounts of lightmaps, especially when using<br />external lightmaps.</p>
|
||||
|
||||
|
||||
<h2 id="Converting-to-ASE-prefabs">Converting to ASE prefabs<a href="#Converting-to-ASE-prefabs" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>Use <code>-convert -format ase -shadersasbitmap</code> for this purpose. That way, the<br />created ASE files work as prefabs, and thus contain shader names, instead of<br />texture file names. In a model editor, however, these ASE files will not show<br />up with textures, as modelling software does not support Q3 shaders.</p>
|
||||
|
||||
|
||||
<h2 id="Zero-effort-cel-shading">Zero-effort cel shading<a href="#Zero-effort-cel-shading" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>If you already have a cel shader (in Nexuiz, cel/black_ink), you can compile<br />the map using it easily by adding the option <code>-celshader cel/black_ink</code> to the<br />BSP stage.</p>
|
||||
|
||||
|
||||
<h2 id="MiniMap-generator">MiniMap generator<a href="#MiniMap-generator" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p><div style="float:right"><img src="/attachments/download/18" alt="" /></div></p>
|
||||
|
||||
|
||||
This version of the map compiler can generate minimaps as used by Nexuiz.<br />The specs of the minimap's texture mapping are:
|
||||
<ul>
|
||||
<li>Let M be the rectangle of the world's mins/maxs coordinates.</li>
|
||||
<li>If <code>keepaspect</code> is set: let S be the smallest square completely covering M whose center matches the one of M. Otherwise, let S be M.</li>
|
||||
<li>Let S' be S scaled by factor <code>1/(1-2*border)</code> around the center of S.</li>
|
||||
<li>The "mins" corner of S' corresponds to the top left corner of the image.</li>
|
||||
<li>The "maxs" corner of S' corresponds to the bottom right corner of the image.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="attachments">
|
||||
|
||||
<p><a href="/attachments/12/floodlight.jpg" class="icon icon-attachment">floodlight.jpg</a>
|
||||
<span class="size">(7 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:26:00 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
<p><a href="/attachments/13/exposure.jpg" class="icon icon-attachment">exposure.jpg</a>
|
||||
<span class="size">(27.8 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:26:31 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
<p><a href="/attachments/14/dotproduct-small.jpg" class="icon icon-attachment">dotproduct-small.jpg</a>
|
||||
<span class="size">(25.9 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:29:00 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
<p><a href="/attachments/15/dotproduct2-small.jpg" class="icon icon-attachment">dotproduct2-small.jpg</a>
|
||||
<span class="size">(24.2 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:29:36 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
<p><a href="/attachments/16/dotproductscale-small.jpg" class="icon icon-attachment">dotproductscale-small.jpg</a>
|
||||
<span class="size">(23.3 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:29:54 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
<p><a href="/attachments/17/dotproduct2scale-small.jpg" class="icon icon-attachment">dotproduct2scale-small.jpg</a>
|
||||
<span class="size">(22.8 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:30:08 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
<p><a href="/attachments/18/minimap.jpg" class="icon icon-attachment">minimap.jpg</a>
|
||||
<span class="size">(6.4 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:30:30 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="other-formats">Экспортировать в
|
||||
<span><a href="/projects/netradiant/wiki/Additional_map_compiler_features?format=html&version=9" class="html" rel="nofollow">HTML</a></span>
|
||||
<span><a href="/projects/netradiant/wiki/Additional_map_compiler_features?format=txt&version=9" class="txt" rel="nofollow">TXT</a></span>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span>Загрузка...</span></div>
|
||||
|
||||
<div id="footer">
|
||||
Powered by <a href="http://www.redmine.org/">Redmine</a> © 2006-2010 Jean-Philippe Lang
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
236
docs/Additional_map_editor_features.htm
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
<!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" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>NetRadiant - Additional map editor features - Alientrap Development</title>
|
||||
<meta name="description" content="Redmine" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<link href="application.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<script src="prototype.js" type="text/javascript"></script>
|
||||
<script src="effects.js" type="text/javascript"></script>
|
||||
<script src="dragdrop.js" type="text/javascript"></script>
|
||||
<script src="controls.js" type="text/javascript"></script>
|
||||
<script src="application.js" type="text/javascript"></script>
|
||||
<link href="jstoolbar.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!--[if IE]>
|
||||
<style type="text/css">
|
||||
* html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
|
||||
body {behavior: url(/stylesheets/csshover.htc?1267352889);}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
.question { background-color:#FFEBC1; border:2px solid #FDBD3B; margin-bottom:12px; padding:0px 4px 8px 4px; }
|
||||
td.formatted_questions { text-align: left; white-space: normal}
|
||||
td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
|
||||
</style>
|
||||
<link href="stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!-- page specific tags -->
|
||||
|
||||
<link href="scm.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="top-menu">
|
||||
<div id="account">
|
||||
<ul><li><a href="/login" class="login">Войти</a></li>
|
||||
<li><a href="/account/register" class="register">Регистрация</a></li></ul> </div>
|
||||
|
||||
<ul><li><a href="/" class="home">Домашняя страница</a></li>
|
||||
<li><a href="/projects" class="projects">Проекты</a></li>
|
||||
<li><a href="http://www.redmine.org/guide" class="help">Помощь</a></li></ul></div>
|
||||
|
||||
<div id="header">
|
||||
<div id="quick-search">
|
||||
<form action="/search/index/netradiant" method="get">
|
||||
<input name="wiki_pages" type="hidden" value="1" />
|
||||
<a href="/search/index/netradiant" accesskey="4">Поиск</a>:
|
||||
<input accesskey="f" class="small" id="q" name="q" size="20" type="text" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<h1>NetRadiant</h1>
|
||||
|
||||
<div id="main-menu">
|
||||
<ul><li><a href="/projects/netradiant" class="overview">Просмотр</a></li>
|
||||
<li><a href="/projects/netradiant/activity" class="activity">Активность</a></li>
|
||||
<li><a href="/projects/netradiant/issues" class="issues">Задачи</a></li>
|
||||
<li><a href="/projects/netradiant/news" class="news">Новости</a></li>
|
||||
<li><a href="/projects/netradiant/documents" class="documents">Документы</a></li>
|
||||
<li><a href="/projects/netradiant/wiki" class="wiki selected">Wiki</a></li>
|
||||
<li><a href="/projects/netradiant/boards" class="boards">Форумы</a></li>
|
||||
<li><a href="/projects/netradiant/files" class="files">Файлы</a></li>
|
||||
<li><a href="/projects/netradiant/repository" class="repository">Хранилище</a></li>
|
||||
<li><a href="/ezfaq/index/netradiant" class="ezfaq">FAQ</a></li></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="" id="main">
|
||||
<div id="sidebar">
|
||||
|
||||
<h3>Wiki</h3>
|
||||
|
||||
<a href="/projects/netradiant/wiki">Стартовая страница</a><br />
|
||||
<a href="/projects/netradiant/wiki/Page_index">Оглавление</a><br />
|
||||
<a href="/projects/netradiant/wiki/Date_index">История страниц</a><br />
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div class="contextual">
|
||||
|
||||
|
||||
<span id="watcher"></span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/projects/netradiant/wiki/Additional_map_editor_features/history" class="icon icon-history">История</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="wiki">
|
||||
<h1 id="Additional-map-editor-features">Additional map editor features<a href="#Additional-map-editor-features" class="wiki-anchor">¶</a></h1>
|
||||
|
||||
|
||||
<p>The following features were added to the map editor:</p>
|
||||
|
||||
|
||||
<h2 id="OBJ-model-format"><code>OBJ</code> model format<a href="#OBJ-model-format" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p><code>OBJ</code> files can be used as models, and texture information is taken from their associated <code>MTL</code> file.</p>
|
||||
|
||||
|
||||
<p>In Blender, make sure "use material groups" is enabled when exporting.</p>
|
||||
|
||||
|
||||
<h2 id="Expand-selection-to-whole-entities">Expand selection to whole entities<a href="#Expand-selection-to-whole-entities" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>Ctrl-Alt-E now selects the parent entity, too. Useful for duplicating the entity, as opposed to just its brushes.</p>
|
||||
|
||||
|
||||
<h2 id="Targeting-lines">Targeting lines<a href="#Targeting-lines" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>Targeting lines are also shown for <code>target2</code>, <code>target3</code>, <code>target4</code> and <code>killtarget</code> keys to match usage in Nexuiz.</p>
|
||||
|
||||
|
||||
<h2 id="Non-modal-Rotate-and-Scale-dialogs">Non-modal Rotate and Scale dialogs<a href="#Non-modal-Rotate-and-Scale-dialogs" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>Rotate and Scale dialogs are no longer modal, so you can keep the dialog open and e.g. change the selection and then apply another rotation.</p>
|
||||
|
||||
|
||||
<h2 id="Four-pane-view-improvement">Four-pane view improvement<a href="#Four-pane-view-improvement" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>In the four-pane view, Ctrl-Tab now centers all three 2D views to the currently selected entity, so you do not need to hold Shift too.</p>
|
||||
|
||||
|
||||
<h2 id="Strafe-mode">Strafe mode<a href="#Strafe-mode" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>The option "Strafe mode" can be changed to select the strafing behaviour: default mode "Both" matches GtkRadiant 1.5: Ctrl enables sideways strafing, Shift-Ctrl enables forward moving. The other modes allow to switch between one of these two behaviours permanently, so Shift-Ctrl can be used to select faces while moving around in the 3D view.</p>
|
||||
|
||||
|
||||
<h2 id="Regrouping-entities">Regrouping entities<a href="#Regrouping-entities" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>When having a brush of an entity selected, this command removes that brush from the entity and puts it in worldspawn. When having a brush and an entity selected, it puts the brush into that entity (note: do this in the entity list or using the Ctrl-Alt-E bind "Expand selection to whole entities" to make sure that the entity, and not just one of its brushes, is selected). That way, you can insert/remove brushes from entities without having to retype all entity keys or redoing the brushwork.</p>
|
||||
|
||||
|
||||
<h2 id="Clone-selection-change">Clone selection change<a href="#Clone-selection-change" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>"Clone selection" (space) no longer changes <code>targetname</code>/<code>target</code> of entities, so you can clone to create many entities to target one. If you want to change targetname/target when cloning like Radiant did before, use Shift+Space.</p>
|
||||
|
||||
|
||||
<h2 id="The-clip-line">The clip line<a href="#The-clip-line" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p><div style="float:right"><img src="clipline-small.png" alt="" /></div></p>
|
||||
|
||||
|
||||
<p>The clip tool shows an extra line pointing in the direction of what's getting erased when you hit Enter. That way, the mistake of accidentally deleting the wrong half when clipping can be avoided.</p>
|
||||
|
||||
|
||||
<h2 class="clearbefore" id="Automatic-game-configuration">Automatic game configuration<a href="#Automatic-game-configuration" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>NetRadiant detects being inside a Q2World or Nexuiz install, and automatically configures its engine path to it. Other games can be easily added to the list.</p>
|
||||
|
||||
|
||||
<h2 id="Editable-keyboard-shortcuts">Editable keyboard shortcuts<a href="#Editable-keyboard-shortcuts" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>The Help/Keyboard shortcuts dialog now allows changing the shortcuts, so you can e.g. enable previously unbound features.</p>
|
||||
|
||||
|
||||
<h2 id="Portable-NetRadiant">Portable NetRadiant<a href="#Portable-NetRadiant" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<p>If you create a subdirectory called <code>settings</code> in your Radiant install, the install becomes "portable", that means it'll write its settings there, and not in a user-specific directory. Useful to take Radiant together with its settings with you on an USB stick.</p>
|
||||
|
||||
|
||||
<p>Makes especially much sense in conjunction with automatic game configuration.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="attachments">
|
||||
|
||||
<p><a href="/attachments/10/clipline-small.png" class="icon icon-attachment">clipline-small.png</a>
|
||||
<span class="size">(1.8 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:13:56 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
<p><a href="/attachments/11/clipline.png" class="icon icon-attachment">clipline.png</a>
|
||||
<span class="size">(400.6 КБ)</span>
|
||||
|
||||
|
||||
<span class="author">divVerent, Вт, 05 мая 2009, 13:14:57 -0400</span>
|
||||
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="other-formats">Экспортировать в
|
||||
<span><a href="/projects/netradiant/wiki/Additional_map_editor_features?format=html&version=8" class="html" rel="nofollow">HTML</a></span>
|
||||
<span><a href="/projects/netradiant/wiki/Additional_map_editor_features?format=txt&version=8" class="txt" rel="nofollow">TXT</a></span>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span>Загрузка...</span></div>
|
||||
|
||||
<div id="footer">
|
||||
Powered by <a href="http://www.redmine.org/">Redmine</a> © 2006-2010 Jean-Philippe Lang
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
385
docs/Complete_list_of_command_line_parameters.htm
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
<!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" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>NetRadiant - Complete list of command line parameters - Alientrap Development</title>
|
||||
<meta name="description" content="Redmine" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<link href="application.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<script src="prototype.js" type="text/javascript"></script>
|
||||
<script src="effects.js" type="text/javascript"></script>
|
||||
<script src="dragdrop.js" type="text/javascript"></script>
|
||||
<script src="controls.js" type="text/javascript"></script>
|
||||
<script src="application.js" type="text/javascript"></script>
|
||||
<link href="jstoolbar.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!--[if IE]>
|
||||
<style type="text/css">
|
||||
* html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
|
||||
body {behavior: url(/stylesheets/csshover.htc?1267352889);}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
.question { background-color:#FFEBC1; border:2px solid #FDBD3B; margin-bottom:12px; padding:0px 4px 8px 4px; }
|
||||
td.formatted_questions { text-align: left; white-space: normal}
|
||||
td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
|
||||
</style>
|
||||
<link href="stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!-- page specific tags -->
|
||||
|
||||
<link href="scm.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="top-menu">
|
||||
<div id="account">
|
||||
<ul><li><a href="/login" class="login">Войти</a></li>
|
||||
<li><a href="/account/register" class="register">Регистрация</a></li></ul> </div>
|
||||
|
||||
<ul><li><a href="/" class="home">Домашняя страница</a></li>
|
||||
<li><a href="/projects" class="projects">Проекты</a></li>
|
||||
<li><a href="http://www.redmine.org/guide" class="help">Помощь</a></li></ul></div>
|
||||
|
||||
<div id="header">
|
||||
<div id="quick-search">
|
||||
<form action="/search/index/netradiant" method="get">
|
||||
<input name="wiki_pages" type="hidden" value="1" />
|
||||
<a href="/search/index/netradiant" accesskey="4">Поиск</a>:
|
||||
<input accesskey="f" class="small" id="q" name="q" size="20" type="text" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<h1>NetRadiant</h1>
|
||||
|
||||
<div id="main-menu">
|
||||
<ul><li><a href="/projects/netradiant" class="overview">Просмотр</a></li>
|
||||
<li><a href="/projects/netradiant/activity" class="activity">Активность</a></li>
|
||||
<li><a href="/projects/netradiant/issues" class="issues">Задачи</a></li>
|
||||
<li><a href="/projects/netradiant/news" class="news">Новости</a></li>
|
||||
<li><a href="/projects/netradiant/documents" class="documents">Документы</a></li>
|
||||
<li><a href="/projects/netradiant/wiki" class="wiki selected">Wiki</a></li>
|
||||
<li><a href="/projects/netradiant/boards" class="boards">Форумы</a></li>
|
||||
<li><a href="/projects/netradiant/files" class="files">Файлы</a></li>
|
||||
<li><a href="/projects/netradiant/repository" class="repository">Хранилище</a></li>
|
||||
<li><a href="/ezfaq/index/netradiant" class="ezfaq">FAQ</a></li></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="" id="main">
|
||||
<div id="sidebar">
|
||||
|
||||
<h3>Wiki</h3>
|
||||
|
||||
<a href="/projects/netradiant/wiki">Стартовая страница</a><br />
|
||||
<a href="/projects/netradiant/wiki/Page_index">Оглавление</a><br />
|
||||
<a href="/projects/netradiant/wiki/Date_index">История страниц</a><br />
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div class="contextual">
|
||||
|
||||
|
||||
<span id="watcher"></span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/projects/netradiant/wiki/Complete_list_of_command_line_parameters/history" class="icon icon-history">История</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="wiki">
|
||||
<h1 id="Complete-list-of-command-line-parameters">Complete list of command line parameters<a href="#Complete-list-of-command-line-parameters" class="wiki-anchor">¶</a></h1>
|
||||
|
||||
|
||||
<h2 id="Common-options">Common options<a href="#Common-options" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-connect</code> address:</strong> Talk to a NetRadiant instance using a specific XML based protocol</li>
|
||||
<li><strong><code>-force</code>:</strong> Allow reading some broken/unsupported BSP files e.g. when decompiling, may also crash</li>
|
||||
<li><strong><code>-fs_basepath</code> path:</strong> Sets the given path as main directory of the game (can be used more than once to look in multiple paths)</li>
|
||||
<li><strong><code>-fs_game</code> gamename:</strong> Sets a different game directory name (default for Q3A: baseq3)</li>
|
||||
<li><strong><code>-fs_homebase</code> dir:</strong> Specifies where the user home directory name is on Linux (default for Q3A: .q3a)</li>
|
||||
<li><strong><code>-game</code> gamename:</strong> Load settings for the given game (default: quake3)</li>
|
||||
<li><strong><code>-subdivisions</code> F:</strong> multiplier for patch subdivisions quality</li>
|
||||
<li><strong><code>-threads</code> N:</strong> number of threads to use</li>
|
||||
<li><strong><code>-v</code>:</strong> Verbose mode</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="BSP-stage">BSP stage<a href="#BSP-stage" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-bsp</code> ... filename.map:</strong> Switch that enters this stage</li>
|
||||
<li><strong><code>-altsplit</code>:</strong> Alternate BSP tree splitting weights (should give more fps)</li>
|
||||
<li><strong><code>-celshader</code> shadername:</strong> Sets a global cel shader name</li>
|
||||
<li><strong><code>-custinfoparms</code>:</strong> Read scripts/custinfoparms.txt</li>
|
||||
<li><strong><code>-debuginset</code>:</strong> Push all triangle vertexes towards the triangle center</li>
|
||||
<li><strong><code>-debugportals</code>:</strong> Make BSP portals visible in the map</li>
|
||||
<li><strong><code>-debugsurfaces</code>:</strong> Color the vertexes according to the index of the surface</li>
|
||||
<li><strong><code>-deep</code>:</strong> Use detail brushes in the BSP tree, but at lowest priority (should give more fps)</li>
|
||||
<li><strong><code>-de</code> F:</strong> Distance epsilon for plane snapping etc.</li>
|
||||
<li><strong><code>-fakemap</code>:</strong> Write fakemap.map containing all world brushes</li>
|
||||
<li><strong><code>-flares</code>:</strong> Turn on support for flares (TEST?)</li>
|
||||
<li><strong><code>-flat</code>:</strong> Enable flat shading (good for combining with -celshader)</li>
|
||||
<li><strong><code>-fulldetail</code>:</strong> Treat detail brushes as structural ones</li>
|
||||
<li><strong><code>-leaktest</code>:</strong> Abort if a leak was found</li>
|
||||
<li><strong><code>-meta</code>:</strong> Combine adjacent triangles of the same texture to surfaces (ALWAYS USE THIS)</li>
|
||||
<li><strong><code>-minsamplesize</code> N:</strong> Sets minimum lightmap resolution in luxels/qu</li>
|
||||
<li><strong><code>-mi</code> N:</strong> Sets the maximum number of indexes per surface</li>
|
||||
<li><strong><code>-mv</code> N:</strong> Sets the maximum number of vertices of a lightmapped surface</li>
|
||||
<li><strong><code>-ne</code> F:</strong> Normal epsilon for plane snapping etc.</li>
|
||||
<li><strong><code>-nocurves</code>:</strong> Turn off support for patches</li>
|
||||
<li><strong><code>-nodetail</code>:</strong> Leave out detail brushes</li>
|
||||
<li><strong><code>-noflares</code>:</strong> Turn off support for flares</li>
|
||||
<li><strong><code>-nofog</code>:</strong> Turn off support for fog volumes</li>
|
||||
<li><strong><code>-nohint</code>:</strong> Turn off support for hint brushes</li>
|
||||
<li><strong><code>-nosubdivide</code>:</strong> Turn off support for <code>q3map_tessSize</code> (breaks water vertex deforms)</li>
|
||||
<li><strong><code>-notjunc</code>:</strong> Do not fix T-junctions (causes cracks between triangles, do not use)</li>
|
||||
<li><strong><code>-nowater</code>:</strong> Turn off support for water, slime or lava (Stef, this is for you)</li>
|
||||
<li><strong><code>-np</code> A:</strong> Force all surfaces to be nonplanar with a given shade angle</li>
|
||||
<li><strong><code>-onlyents</code>:</strong> Only update entities in the BSP</li>
|
||||
<li><strong><code>-patchmeta</code>:</strong> Turn patches into triangle meshes for display</li>
|
||||
<li><strong><code>-rename</code>:</strong> Append "\_bsp" suffix to misc\_model shaders (needed for SoF2)</li>
|
||||
<li><strong><code>-samplesize</code> N:</strong> Sets default lightmap resolution in luxels/qu</li>
|
||||
<li><strong><code>-skyfix</code>:</strong> Turn sky box into six surfaces to work around ATI problems</li>
|
||||
<li><strong><code>-snap</code> N:</strong> Snap brush bevel planes to the given number of units</li>
|
||||
<li><strong><code>-tempname</code> filename.map:</strong> Read the MAP file from the given file name</li>
|
||||
<li><strong><code>-texrange</code> N:</strong> Limit per-surface texture range to the given number of units, and subdivide surfaces like with <code>q3map_tessSize</code> if this is not met</li>
|
||||
<li><strong><code>-tmpout</code>:</strong> Write the BSP file to /tmp</li>
|
||||
<li><strong><code>-verboseentities</code>:</strong> Enable <code>-v</code> only for map entities, not for the world</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="VIS-stage">VIS stage<a href="#VIS-stage" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-vis</code> ... filename.map:</strong> Switch that enters this stage</li>
|
||||
<li><strong><code>-fast</code>:</strong> Very fast and crude vis calculation</li>
|
||||
<li><strong><code>-mergeportals</code>:</strong> The less crude half of <code>-merge</code>, makes vis sometimes much faster but doesn't hurt fps usually</li>
|
||||
<li><strong><code>-merge</code>:</strong> Faster but still okay vis calculation</li>
|
||||
<li><strong><code>-nopassage</code>:</strong> Just use PortalFlow vis (usually less fps)</li>
|
||||
<li><strong><code>-nosort</code>:</strong> Do not sort the portals before calculating vis (usually slower)</li>
|
||||
<li><strong><code>-passageOnly</code>:</strong> Just use PassageFlow vis (usually less fps)</li>
|
||||
<li><strong><code>-saveprt</code>:</strong> Keep the PRT file after running vis (so you can run vis again)</li>
|
||||
<li><strong><code>-tmpin</code>:</strong> Use /tmp folder for input</li>
|
||||
<li><strong><code>-tmpout</code>:</strong> Use /tmp folder for output</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="LIGHT-stage">LIGHT stage<a href="#LIGHT-stage" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-light</code> ... filename.map:</strong> Switch that enters this stage</li>
|
||||
<li><strong><code>-vlight</code> ... filename.map:</strong> Deprecated alias for <code>-light -fast</code> ... filename.map</li>
|
||||
<li><strong><code>-approx</code> N:</strong> Vertex light approximation tolerance (never use in conjunction with deluxemapping)</li>
|
||||
<li><strong><code>-areascale</code> F, <code>-area</code> F:</strong> Scaling factor for area lights (surfacelight)</li>
|
||||
<li><strong><code>-border</code>:</strong> Add a red border to lightmaps for debugging</li>
|
||||
<li><strong><code>-bouncegrid</code>:</strong> Also compute radiosity on the light grid</li>
|
||||
<li><strong><code>-bounceonly</code>:</strong> Only compute radiosity</li>
|
||||
<li><strong><code>-bouncescale</code> F:</strong> Scaling factor for radiosity</li>
|
||||
<li><strong><code>-bounce</code> N:</strong> Number of bounces for radiosity</li>
|
||||
<li><strong><code>-cheapgrid</code>:</strong> Use <code>-cheap</code> style lighting for radiosity</li>
|
||||
<li><strong><code>-cheap</code>:</strong> Abort vertex light calculations when white is reached</li>
|
||||
<li><strong><code>-compensate</code> F:</strong> Lightmap compensate (darkening factor applied after everything else)</li>
|
||||
<li><strong><code>-cpma</code>:</strong> CPMA vertex lighting mode</li>
|
||||
<li><strong><code>-custinfoparms</code>:</strong> Read scripts/custinfoparms.txt</li>
|
||||
<li><strong><code>-dark</code>:</strong> Darken lightmap seams</li>
|
||||
<li><strong><code>-debugaxis</code>:</strong> Color the lightmaps according to the lightmap axis</li>
|
||||
<li><strong><code>-debugcluster</code>:</strong> Color the lightmaps according to the index of the cluster</li>
|
||||
<li><strong><code>-debugdeluxe</code>:</strong> Show deluxemaps on the lightmap</li>
|
||||
<li><strong><code>-debugnormals</code>:</strong> Color the lightmaps according to the direction of the surface normal</li>
|
||||
<li><strong><code>-debugorigin</code>:</strong> Color the lightmaps according to the origin of the luxels</li>
|
||||
<li><strong><code>-debugsurfaces</code>, <code>-debugsurface</code>:</strong> Color the lightmaps according to the index of the surface</li>
|
||||
<li><strong><code>-debugunused</code>:</strong> This option does nothing</li>
|
||||
<li><strong><code>-debug</code>:</strong> Mark the lightmaps according to the cluster: unmapped clusters get yellow, occluded ones get pink, flooded ones get blue overlay color, otherwise red</li>
|
||||
<li><strong><code>-deluxemode 0</code>:</strong> Use modelspace deluxemaps (DarkPlaces)</li>
|
||||
<li><strong><code>-deluxemode 1</code>:</strong> Use tangentspace deluxemaps</li>
|
||||
<li><strong><code>-deluxe</code>, <code>-deluxemap</code>:</strong> Enable deluxemapping (light direction maps)</li>
|
||||
<li><strong><code>-dirtdebug</code>, <code>-debugdirt</code>:</strong> Store the dirtmaps as lightmaps for debugging</li>
|
||||
<li><strong><code>-dirtdepth</code>:</strong> Dirtmapping depth</li>
|
||||
<li><strong><code>-dirtgain</code>:</strong> Dirtmapping exponent</li>
|
||||
<li><strong><code>-dirtmode 0</code>:</strong> Ordered direction dirtmapping</li>
|
||||
<li><strong><code>-dirtmode 1</code>:</strong> Randomized direction dirtmapping</li>
|
||||
<li><strong><code>-dirtscale</code>:</strong> Dirtmapping scaling factor</li>
|
||||
<li><strong><code>-dirty</code>:</strong> Enable dirtmapping</li>
|
||||
<li><strong><code>-dump</code>:</strong> Dump radiosity from <code>-bounce</code> into numbered MAP file prefabs</li>
|
||||
<li><strong><code>-export</code>:</strong> Export lightmaps when compile finished (like <code>-export</code> mode)</li>
|
||||
<li><strong><code>-exposure</code> F:</strong> Lightmap exposure to better support overbright spots</li>
|
||||
<li><strong><code>-external</code>:</strong> Force external lightmaps even if at size of internal lightmaps</li>
|
||||
<li><strong><code>-extravisnudge</code>:</strong> Broken feature to nudge the luxel origin to a better vis cluster</li>
|
||||
<li><strong><code>-extrawide</code>:</strong> Deprecated alias for <code>-super 2 -filter</code></li>
|
||||
<li><strong><code>-extra</code>:</strong> Deprecated alias for <code>-super 2</code></li>
|
||||
<li><strong><code>-fastbounce</code>:</strong> Use <code>-fast</code> style lighting for radiosity</li>
|
||||
<li><strong><code>-faster</code>:</strong> Use a faster falloff curve for lighting; also implies <code>-fast</code></li>
|
||||
<li><strong><code>-fastgrid</code>:</strong> Use <code>-fast</code> style lighting for the light grid</li>
|
||||
<li><strong><code>-fast</code>:</strong> Ignore tiny light contributions</li>
|
||||
<li><strong><code>-filter</code>:</strong> Lightmap filtering</li>
|
||||
<li><strong><code>-floodlight</code>:</strong> Enable floodlight (zero-effort somewhat decent lighting)</li>
|
||||
<li><strong><code>-gamma</code> F:</strong> Lightmap gamma</li>
|
||||
<li><strong><code>-gridambientscale</code> F:</strong> Scaling factor for the light grid ambient components only</li>
|
||||
<li><strong><code>-gridscale</code> F:</strong> Scaling factor for the light grid only</li>
|
||||
<li><strong><code>-keeplights</code>:</strong> Keep light entities in the BSP file after compile</li>
|
||||
<li><strong><code>-lightmapdir</code> directory:</strong> Directory to store external lightmaps (default: same as map name without extension)</li>
|
||||
<li><strong><code>-lightmapsize</code> N:</strong> Size of lightmaps to generate (must be a power of two)</li>
|
||||
<li><strong><code>-lomem</code>:</strong> Low memory but slower lighting mode</li>
|
||||
<li><strong><code>-lowquality</code>:</strong> Low quality floodlight (appears to currently break floodlight)</li>
|
||||
<li><strong><code>-minsamplesize</code> N:</strong> Sets minimum lightmap resolution in luxels/qu</li>
|
||||
<li><strong><code>-nocollapse</code>:</strong> Do not collapse identical lightmaps</li>
|
||||
<li><strong><code>-nodeluxe</code>, <code>-nodeluxemap</code>:</strong> Disable deluxemapping</li>
|
||||
<li><strong><code>-nogrid</code>:</strong> Disable grid light calculation (makes all entities fullbright)</li>
|
||||
<li><strong><code>-nolightmapsearch</code>:</strong> Do not optimize lightmap packing for GPU memory usage (as doing so costs fps)</li>
|
||||
<li><strong><code>-normalmap</code>:</strong> Color the lightmaps according to the direction of the surface normal (TODO is this identical to <code>-debugnormals</code>?)</li>
|
||||
<li><strong><code>-nostyle</code>, <code>-nostyles</code>:</strong> Disable support for light styles</li>
|
||||
<li><strong><code>-nosurf</code>:</strong> Disable tracing against surfaces (only uses BSP nodes then)</li>
|
||||
<li><strong><code>-notrace</code>:</strong> Disable shadow occlusion</li>
|
||||
<li><strong><code>-novertex</code>:</strong> Disable vertex lighting</li>
|
||||
<li><strong><code>-patchshadows</code>:</strong> Cast shadows from patches</li>
|
||||
<li><strong><code>-pointscale</code> F, <code>-point</code> F:</strong> Scaling factor for point lights (light entities)</li>
|
||||
<li><strong><code>-q3</code>:</strong> Use nonlinear falloff curve by default (like Q3A)</li>
|
||||
<li><strong><code>-samplescale</code> F:</strong> Scales all lightmap resolutions</li>
|
||||
<li><strong><code>-samplesize</code> N:</strong> Sets default lightmap resolution in luxels/qu</li>
|
||||
<li><strong><code>-samples</code> N:</strong> Adaptive supersampling quality</li>
|
||||
<li><strong><code>-scale</code> F:</strong> Scaling factor for all light types</li>
|
||||
<li><strong><code>-shadeangle</code> A:</strong> Angle for phong shading</li>
|
||||
<li><strong><code>-shade</code>:</strong> Enable phong shading at default shade angle</li>
|
||||
<li><strong><code>-skyscale</code> F, <code>-sky</code> F:</strong> Scaling factor for sky and sun light</li>
|
||||
<li><strong><code>-smooth</code>:</strong> Deprecated alias for <code>-samples 2</code></li>
|
||||
<li><strong><code>-style</code>, <code>-styles</code>:</strong> Enable support for light styles</li>
|
||||
<li><strong><code>-sunonly</code>:</strong> Only compute sun light</li>
|
||||
<li><strong><code>-super</code> N, <code>-supersample</code> N:</strong> Ordered grid supersampling quality</li>
|
||||
<li><strong><code>-thresh</code> F:</strong> Triangle subdivision threshold</li>
|
||||
<li><strong><code>-trianglecheck</code>:</strong> Broken check that should ensure luxels apply to the right triangle</li>
|
||||
<li><strong><code>-trisoup</code>:</strong> Convert brush faces to triangle soup</li>
|
||||
<li><strong><code>-wolf</code>:</strong> Use linear falloff curve by default (like W:ET)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Analyzing-BSP-like-file-structure">Analyzing BSP-like file structure<a href="#Analyzing-BSP-like-file-structure" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-analyze</code> ... filename.bsp:</strong> Switch that enters this mode</li>
|
||||
<li><strong><code>-lumpswap</code>:</strong> Swap byte order in the lumps</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Converting-xx-Decompiling">Converting & Decompiling<a href="#Converting-xx-Decompiling" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-convert</code> ... filename.bsp:</strong> Switch that enters this mode</li>
|
||||
<li><strong><code>-de</code> number:</strong> Distance epsilon for the conversion</li>
|
||||
<li><strong><code>-format</code> converter:</strong> Select the converter (available: map, ase, or game names)</li>
|
||||
<li><strong><code>-ne</code> F:</strong> Normal epsilon for the conversion</li>
|
||||
<li><strong><code>-shadersasbitmap</code>:</strong> (only for ase) use the shader names as *BITMAP key so they work as prefabs</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Exporting-lightmaps">Exporting lightmaps<a href="#Exporting-lightmaps" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-export</code> filename.bsp:</strong> Copies lightmaps from the BSP to filename/lightmap_0000.tga ff</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Fixing-AAS-checksum">Fixing AAS checksum<a href="#Fixing-AAS-checksum" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-fixaas</code> filename.bsp:</strong> Switch that enters this mode</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Get-info-about-BSP-file">Get info about BSP file<a href="#Get-info-about-BSP-file" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-info</code> filename.bsp:</strong> Switch that enters this mode</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Importing-lightmaps">Importing lightmaps<a href="#Importing-lightmaps" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-import</code> filename.bsp:</strong> Copies lightmaps from filename/lightmap_0000.tga ff into the BSP</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="MiniMap">MiniMap<a href="#MiniMap" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-minimap</code> ... filename.bsp:</strong> Creates a minimap of the BSP, by default writes to <code>../gfx/filename_mini.tga</code></li>
|
||||
<li><strong><code>-black</code>:</strong> Write the minimap as a black-on-transparency RGBA32 image</li>
|
||||
<li><strong><code>-boost</code> F:</strong> Sets the contrast boost value (higher values make a brighter image); contrast boost is somewhat similar to gamma, but continuous even at zero</li>
|
||||
<li><strong><code>-border</code> F:</strong> Sets the amount of border pixels relative to the total image size</li>
|
||||
<li><strong><code>-gray</code>:</strong> Write the minimap as a white-on-black GRAY8 image</li>
|
||||
<li><strong><code>-keepaspect</code>:</strong> Ensure the aspect ratio is kept (the minimap is then letterboxed to keep aspect)</li>
|
||||
<li><strong><code>-minmax</code> xmin ymin zmin xmax ymax zmax:</strong> Forces specific map dimensions (note: the minimap actually uses these dimensions, scaled to the target size while keeping aspect with centering, and 1/64 of border appended to all sides)</li>
|
||||
<li><strong><code>-nokeepaspect</code>:</strong> Do not ensure the aspect ratio is kept (makes it easier to use the image in your code, but looks bad together with sharpening)</li>
|
||||
<li><strong><code>-o</code> filename.tga:</strong> Sets the output file name</li>
|
||||
<li><strong><code>-random</code> N:</strong> Sets the randomized supersampling count (cannot be combined with <code>-samples</code>)</li>
|
||||
<li><strong><code>-samples</code> N:</strong> Sets the ordered supersampling count (cannot be combined with <code>-random</code>)</li>
|
||||
<li><strong><code>-sharpen</code> F:</strong> Sets the sharpening coefficient</li>
|
||||
<li><strong><code>-size</code> N:</strong> Sets the width and height of the output image</li>
|
||||
<li><strong><code>-white</code>:</strong> Write the minimap as a white-on-transparency RGBA32 image</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Scaling">Scaling<a href="#Scaling" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>-scale</code> S filename.bsp:</strong> Scale uniformly</li>
|
||||
<li><strong><code>-scale</code> SX SY SZ filename.bsp:</strong> Scale non-uniformly</li>
|
||||
<li><strong><code>-scale -tex</code> S filename.bsp:</strong> Scale uniformly without texture lock</li>
|
||||
<li><strong><code>-scale -tex</code> SX SY SZ filename.bsp:</strong> Scale non-uniformly without texture lock</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="other-formats">Экспортировать в
|
||||
<span><a href="/projects/netradiant/wiki/Complete_list_of_command_line_parameters?format=html&version=3" class="html" rel="nofollow">HTML</a></span>
|
||||
<span><a href="/projects/netradiant/wiki/Complete_list_of_command_line_parameters?format=txt&version=3" class="txt" rel="nofollow">TXT</a></span>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span>Загрузка...</span></div>
|
||||
|
||||
<div id="footer">
|
||||
Powered by <a href="http://www.redmine.org/">Redmine</a> © 2006-2010 Jean-Philippe Lang
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
262
docs/Complete_list_of_entity_keys.htm
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
<!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" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>NetRadiant - Complete list of entity keys - Alientrap Development</title>
|
||||
<meta name="description" content="Redmine" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<link href="application.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<script src="prototype.js" type="text/javascript"></script>
|
||||
<script src="effects.js" type="text/javascript"></script>
|
||||
<script src="dragdrop.js" type="text/javascript"></script>
|
||||
<script src="controls.js" type="text/javascript"></script>
|
||||
<script src="application.js" type="text/javascript"></script>
|
||||
<link href="jstoolbar.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!--[if IE]>
|
||||
<style type="text/css">
|
||||
* html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
|
||||
body {behavior: url(/stylesheets/csshover.htc?1267352889);}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
.question { background-color:#FFEBC1; border:2px solid #FDBD3B; margin-bottom:12px; padding:0px 4px 8px 4px; }
|
||||
td.formatted_questions { text-align: left; white-space: normal}
|
||||
td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
|
||||
</style>
|
||||
<link href="stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!-- page specific tags -->
|
||||
|
||||
<link href="scm.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="top-menu">
|
||||
<div id="account">
|
||||
<ul><li><a href="/login" class="login">Войти</a></li>
|
||||
<li><a href="/account/register" class="register">Регистрация</a></li></ul> </div>
|
||||
|
||||
<ul><li><a href="/" class="home">Домашняя страница</a></li>
|
||||
<li><a href="/projects" class="projects">Проекты</a></li>
|
||||
<li><a href="http://www.redmine.org/guide" class="help">Помощь</a></li></ul></div>
|
||||
|
||||
<div id="header">
|
||||
<div id="quick-search">
|
||||
<form action="/search/index/netradiant" method="get">
|
||||
<input name="wiki_pages" type="hidden" value="1" />
|
||||
<a href="/search/index/netradiant" accesskey="4">Поиск</a>:
|
||||
<input accesskey="f" class="small" id="q" name="q" size="20" type="text" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<h1>NetRadiant</h1>
|
||||
|
||||
<div id="main-menu">
|
||||
<ul><li><a href="/projects/netradiant" class="overview">Просмотр</a></li>
|
||||
<li><a href="/projects/netradiant/activity" class="activity">Активность</a></li>
|
||||
<li><a href="/projects/netradiant/issues" class="issues">Задачи</a></li>
|
||||
<li><a href="/projects/netradiant/news" class="news">Новости</a></li>
|
||||
<li><a href="/projects/netradiant/documents" class="documents">Документы</a></li>
|
||||
<li><a href="/projects/netradiant/wiki" class="wiki selected">Wiki</a></li>
|
||||
<li><a href="/projects/netradiant/boards" class="boards">Форумы</a></li>
|
||||
<li><a href="/projects/netradiant/files" class="files">Файлы</a></li>
|
||||
<li><a href="/projects/netradiant/repository" class="repository">Хранилище</a></li>
|
||||
<li><a href="/ezfaq/index/netradiant" class="ezfaq">FAQ</a></li></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="" id="main">
|
||||
<div id="sidebar">
|
||||
|
||||
<h3>Wiki</h3>
|
||||
|
||||
<a href="/projects/netradiant/wiki">Стартовая страница</a><br />
|
||||
<a href="/projects/netradiant/wiki/Page_index">Оглавление</a><br />
|
||||
<a href="/projects/netradiant/wiki/Date_index">История страниц</a><br />
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div class="contextual">
|
||||
|
||||
|
||||
<span id="watcher"></span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/projects/netradiant/wiki/Complete_list_of_entity_keys/history" class="icon icon-history">История</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="wiki">
|
||||
<h1 id="Complete-list-of-entity-keys">Complete list of entity keys<a href="#Complete-list-of-entity-keys" class="wiki-anchor">¶</a></h1>
|
||||
|
||||
|
||||
<ul>
|
||||
<li>On all entities
|
||||
<ul>
|
||||
<li><strong><code>angle</code>:</strong> shorthand for just setting the yaw angle</li>
|
||||
<li><strong><code>angles</code>:</strong> angles vector</li>
|
||||
<li><strong><code>origin</code>:</strong> origin vector</li>
|
||||
<li><strong><code>targetname</code>:</strong> name of the entity so it can be referenced by <strong><code>target</code></strong> keys.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On brush entities, classname <strong><code>func_group</code></strong> and classname <strong><code>misc_model</code></strong>:
|
||||
<ul>
|
||||
<li><strong><code>_castShadows</code>, <code>_cs</code>:</strong> sets whether the entity casts shadows</li>
|
||||
<li><strong><code>_celshader</code>:</strong> <a href="/projects/netradiant/wiki/CelShader" class="wiki-page new">CelShader</a> to use</li>
|
||||
<li><strong><code>_lightmapsamplesize</code>, <code>_samplesize</code>:</strong> sample size to use for surfaces of this entity</li>
|
||||
<li><strong><code>_receiveShadows</code>, <code>_rs</code>:</strong> sets whether the entity receives shadows</li>
|
||||
<li><strong><code>_shadeangle</code>, <code>_smoothnormals</code>, <code>_sn</code>, <code>_smooth</code>:</strong> largest angle between faces to allow to treat them part of the same nonplanar surface</li>
|
||||
<li><strong><code>lightmapscale</code>, <code>_lightmapscale</code>, <code>_ls</code>:</strong> scaling factor for the lightmap resolution</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On brush entities and on classname <strong><code>func_group</code></strong>:
|
||||
<ul>
|
||||
<li><strong><code>_indexmap</code>, <code>alphamap</code>:</strong> file name of index map image for terrain blending</li>
|
||||
<li><strong><code>_layers</code>, <code>layers</code>:</strong> number of layers of the index map image (encoded as brightness levels)</li>
|
||||
<li><strong><code>_offsets</code>, <code>offsets</code>:</strong> space separated list of z offsets</li>
|
||||
<li><strong><code>_shader</code>, <code>shader</code>:</strong> shader name prefix of the index map (when this is set to <code>X</code>, the shader names that are generated will be like <code>textures/X_42</code> and <code>textures/X_23to42</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On brush entities
|
||||
<ul>
|
||||
<li><strong><code>_clone</code>, <code>_ins</code>, <code>_instance</code>:</strong> <strong><code>_clonename</code></strong> field value of a brush entity to clone brushes from (can be used to use the same brush model multiple times)</li>
|
||||
<li><strong><code>_clonename</code>:</strong> see <strong><code>_clone</code></strong></li>
|
||||
<li><strong><code>_patchMeta</code>, <code>patchMeta</code>:</strong> generate a triangle soup from patches in this entity</li>
|
||||
<li><strong><code>_patchQuality</code>:</strong> quality multiplier for patches on this surface when <strong><code>_patchMeta</code></strong> is used</li>
|
||||
<li><strong><code>_patchSubdivide</code>:</strong> absolute quality setting for patches on this surface when <strong><code>_patchMeta</code></strong> is used</li>
|
||||
<li><strong><code>max</code>:</strong> override the <code>maxs</code> vector of this brush entity</li>
|
||||
<li><strong><code>min</code>:</strong> override the <code>mins</code> vector of this brush entity</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On classname <strong><code>worldspawn</code></strong>
|
||||
<ul>
|
||||
<li><strong><code>_ambient</code>, <code>ambient</code>:</strong> amount of ambient light</li>
|
||||
<li><strong><code>_blocksize</code>, <code>blocksize</code>, <code>chopsize</code>:</strong> block size for unconditional BSP subdivisions</li>
|
||||
<li><strong><code>_farplanedist</code>, <code>fogclip</code>, <code>distancecull</code>:</strong> far plane distance for vis culling -- this must be the shortest distance at which nothing can be seen any more due to fog</li>
|
||||
<li><strong><code>_floodlight</code>:</strong> a quintuple of values "r g b dist intensity" to set global floodlight parameters (good defaults are 240 240 255 1024 128)</li>
|
||||
<li><strong><code>_fog</code>, <code>fog</code>:</strong> if set, the whole map is fogged using the given shader name</li>
|
||||
<li><strong><code>_foghull</code>:</strong> must be set to a sky shader when <code>_fog</code> is used</li>
|
||||
<li><strong><code>_ignoreleaks</code>, <code>ignoreleaks</code>:</strong> when set, no leak test is performed</li>
|
||||
<li><strong><code>_keepLights</code>:</strong> if set, <strong><code>light</code></strong> entities are not stripped from the <code>BSP</code> file when compiling</li>
|
||||
<li><strong><code>_mingridlight</code>:</strong> amount of minimum grid light</li>
|
||||
<li><strong><code>_minlight</code>:</strong> amount of minimum light</li>
|
||||
<li><strong><code>_minvertexlight</code>:</strong> amount of minimum vertex light</li>
|
||||
<li><strong><code>_noshadersun</code>:</strong> if set, sun light from shaders is suppressed</li>
|
||||
<li><strong><code>_q3map_cmdline</code>:</strong> written by q3map2; contains the command line the map was compiled with</li>
|
||||
<li><strong><code>_q3map_version</code>:</strong> written by q3map2; contains the version of q3map2 the map was compiled with</li>
|
||||
<li><strong><code>_style42alphagen</code>:</strong> |alphaGen|-like shader definition string for light style 442 (works the same way for all style numbers)</li>
|
||||
<li><strong><code>_style42rgbgen</code>:</strong> |rgbGen|-like shader definition string for light style 42 (works the same way for all style numbers)</li>
|
||||
<li><strong><code>gridsize</code>:</strong> resolution of the light grid</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On classname <strong><code>light</code></strong> and classname <strong><code>lightJunior</code></strong>
|
||||
<ul>
|
||||
<li>Note: <strong><code>lightJunior</code></strong> entities only affect the light grid.</li>
|
||||
<li><strong><code>_anglescale</code>:</strong> scales angle attenuation</li>
|
||||
<li><strong><code>_color</code>:</strong> color of the light</li>
|
||||
<li><strong><code>_deviance</code>, <code>_deviation</code>, <code>_jitter</code>:</strong> position deviance of the samples of a regular light (distributes the light samples in a cube of side length 2*_deviance around the origin), or angle deviance of the sun light samples in radians</li>
|
||||
<li><strong><code>_filterradius</code>, <code>_filteradius</code>, <code>_filter</code>:</strong> filter radius for this light, similar to -light -filter</li>
|
||||
<li><strong><code>_samples</code>:</strong> number of samples to use to get soft shadows from a light</li>
|
||||
<li><strong><code>_sun</code>:</strong> if 1, this light is an infinite sun light</li>
|
||||
<li><strong><code>fade</code>:</strong> Fade factor of light attenuation of linear lights. Linear lights completely vanish at distance <strong><code>light</code></strong>/(<strong><code>fade</code></strong> * 8000), so if you want the light to vanish at distance X, specify <strong><code>light</code></strong>/(8000*X) here.</li>
|
||||
<li><strong><code>light</code>:</strong> intensity factor (default: 300)</li>
|
||||
<li><strong><code>radius</code>:</strong> radius of a spotlight at the target point (default: 64)</li>
|
||||
<li><strong><code>scale</code>:</strong> intensity multiplier</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 1 = linear attenuation (inverted in <code>-wolf</code> lighting mode)</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 2 = no angle attenuation (inverted in <code>-wolf</code> lighting mode)</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 32 = the light color is not normalized</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 64 = force distance attenuation (why did vortex add this, this is always set...?)</li>
|
||||
<li><strong><code>target</code>:</strong> target of a spotlight</li>
|
||||
<li><strong><code>targetname</code>:</strong> when set, the light can be toggled in game by some engine provided way</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On classname <strong><code>light</code></strong>
|
||||
<ul>
|
||||
<li><strong><code>_flare</code>:</strong> when set, this light is a flare without a specified shader</li>
|
||||
<li><strong><code>_flareshader</code>:</strong> shader for a flare surface generated by this light</li>
|
||||
<li><strong><code>_style</code>, <code>style</code>:</strong> light style number</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 16 = light does not affect the grid</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On classname <strong><code>advertisement</code></strong> (QuakeLive only)
|
||||
<ul>
|
||||
<li>Brushes/Patches: must be a single rectangular patch surface where the ad will be placed</li>
|
||||
<li><strong><code>cellId</code>:</strong> identifier of the ad, must be used only once (??)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On classname <strong><code>_decal</code></strong>
|
||||
<ul>
|
||||
<li>Brushes/Patches: must be a single rectangular patch surface</li>
|
||||
<li><strong><code>target</code>:</strong> positional target to set the projection direction of the decal</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On classname <strong><code>misc_model</code></strong>
|
||||
<ul>
|
||||
<li><strong><code>_castShadows</code>, <code>_cs</code>:</strong> sets whether the entity casts shadows</li>
|
||||
<li><strong><code>_frame2</code>:</strong> frame of second model to load</li>
|
||||
<li><strong><code>_frame</code>:</strong> frame of model to load</li>
|
||||
<li><strong><code>_receiveShadows</code>, <code>_rs</code>:</strong> sets whether the entity receives shadows</li>
|
||||
<li><strong><code>_remapXXX</code>:</strong> <code>XXX</code> can be any string to allow multiple keys for this; contains a string of the form <code>from;to</code>, and any shader <code>from</code> in the model will be replaced by <code>to</code>; the special value <code>*</code> in <code>from</code> matches all shader names</li>
|
||||
<li><strong><code>model2</code>:</strong> path name of second model to load</li>
|
||||
<li><strong><code>model</code>:</strong> path name of model to load</li>
|
||||
<li><strong><code>modelscale</code>:</strong> scaling factor for the model to include</li>
|
||||
<li><strong><code>modelscale_vec</code>:</strong> non-uniform scaling vector for the model to include</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 1 = in SoF2, append a <code>_RMG_BSP</code> suffix to shader names instead of <code>_BSP</code></li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 2 = generate clipping brushes from the model</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 4 = force this model through meta surface merging</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 8 = when generating clipping planes, perform extrusion using the original normals from the model instead of per-triangle best axial normals</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 16 = when generating clipping planes, perform extrusion using only up or down pointing normals (ideal for terrain)</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 24 = when generating clipping planes, perform extrusion by distance zero (needs engine changes to support zero-volume clipping brushes)</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 32 = turn vertex color from the model into alpha (for terrain blending)</li>
|
||||
<li><strong><code>spawnflags</code>:</strong> 64 = do not let picomodel do surface normal smoothing</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On classname <strong><code>_skybox</code></strong>
|
||||
<ul>
|
||||
<li>To be placed inside a small otherwise hidden room; surfaces in it are scaled up, and visible through skybox surfaces</li>
|
||||
<li><strong><code>_scale</code>:</strong> scaling factor or vector for the portal sky (default: 64)</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="other-formats">Экспортировать в
|
||||
<span><a href="/projects/netradiant/wiki/Complete_list_of_entity_keys?format=html&version" class="html" rel="nofollow">HTML</a></span>
|
||||
<span><a href="/projects/netradiant/wiki/Complete_list_of_entity_keys?format=txt&version" class="txt" rel="nofollow">TXT</a></span>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span>Загрузка...</span></div>
|
||||
|
||||
<div id="footer">
|
||||
Powered by <a href="http://www.redmine.org/">Redmine</a> © 2006-2010 Jean-Philippe Lang
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
254
docs/Complete_list_of_shader_keywords.htm
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
<!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" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>NetRadiant - Complete list of shader keywords - Alientrap Development</title>
|
||||
<meta name="description" content="Redmine" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<link href="application.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<script src="prototype.js" type="text/javascript"></script>
|
||||
<script src="effects.js" type="text/javascript"></script>
|
||||
<script src="dragdrop.js" type="text/javascript"></script>
|
||||
<script src="controls.js" type="text/javascript"></script>
|
||||
<script src="application.js" type="text/javascript"></script>
|
||||
<link href="jstoolbar.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!--[if IE]>
|
||||
<style type="text/css">
|
||||
* html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
|
||||
body {behavior: url(/stylesheets/csshover.htc?1267352889);}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
.question { background-color:#FFEBC1; border:2px solid #FDBD3B; margin-bottom:12px; padding:0px 4px 8px 4px; }
|
||||
td.formatted_questions { text-align: left; white-space: normal}
|
||||
td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
|
||||
</style>
|
||||
<link href="stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!-- page specific tags -->
|
||||
|
||||
<link href="scm.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="top-menu">
|
||||
<div id="account">
|
||||
<ul><li><a href="/login" class="login">Войти</a></li>
|
||||
<li><a href="/account/register" class="register">Регистрация</a></li></ul> </div>
|
||||
|
||||
<ul><li><a href="/" class="home">Домашняя страница</a></li>
|
||||
<li><a href="/projects" class="projects">Проекты</a></li>
|
||||
<li><a href="http://www.redmine.org/guide" class="help">Помощь</a></li></ul></div>
|
||||
|
||||
<div id="header">
|
||||
<div id="quick-search">
|
||||
<form action="/search/index/netradiant" method="get">
|
||||
<input name="wiki_pages" type="hidden" value="1" />
|
||||
<a href="/search/index/netradiant" accesskey="4">Поиск</a>:
|
||||
<input accesskey="f" class="small" id="q" name="q" size="20" type="text" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<h1>NetRadiant</h1>
|
||||
|
||||
<div id="main-menu">
|
||||
<ul><li><a href="/projects/netradiant" class="overview">Просмотр</a></li>
|
||||
<li><a href="/projects/netradiant/activity" class="activity">Активность</a></li>
|
||||
<li><a href="/projects/netradiant/issues" class="issues">Задачи</a></li>
|
||||
<li><a href="/projects/netradiant/news" class="news">Новости</a></li>
|
||||
<li><a href="/projects/netradiant/documents" class="documents">Документы</a></li>
|
||||
<li><a href="/projects/netradiant/wiki" class="wiki selected">Wiki</a></li>
|
||||
<li><a href="/projects/netradiant/boards" class="boards">Форумы</a></li>
|
||||
<li><a href="/projects/netradiant/files" class="files">Файлы</a></li>
|
||||
<li><a href="/projects/netradiant/repository" class="repository">Хранилище</a></li>
|
||||
<li><a href="/ezfaq/index/netradiant" class="ezfaq">FAQ</a></li></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="" id="main">
|
||||
<div id="sidebar">
|
||||
|
||||
<h3>Wiki</h3>
|
||||
|
||||
<a href="/projects/netradiant/wiki">Стартовая страница</a><br />
|
||||
<a href="/projects/netradiant/wiki/Page_index">Оглавление</a><br />
|
||||
<a href="/projects/netradiant/wiki/Date_index">История страниц</a><br />
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div class="contextual">
|
||||
|
||||
|
||||
<span id="watcher"></span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/projects/netradiant/wiki/Complete_list_of_shader_keywords/history" class="icon icon-history">История</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="wiki">
|
||||
<h1 id="Complete-list-of-shader-keywords">Complete list of shader keywords<a href="#Complete-list-of-shader-keywords" class="wiki-anchor">¶</a></h1>
|
||||
|
||||
|
||||
<p>Note: You can append a <code>:q3map</code> suffix to a shader name to make q3map2 use the shader but the engine ignore it.</p>
|
||||
|
||||
|
||||
<p>Note: This list does not contain all possible shader keywords, but just those that q3map2 uses for anything. More keywords are likely to be supported by your engine. Check the documentation or the source code of your engine on this.</p>
|
||||
|
||||
|
||||
<h2 id="Inside-shader-stages">Inside shader stages<a href="#Inside-shader-stages" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>map</code> texture:</strong> loads a texture and displays it repeating</li>
|
||||
<li><strong><code>clampMap</code> texture:</strong> loads a texture and displays it non-repeating</li>
|
||||
<li><strong><code>animMap</code> fps texture texture...:</strong> loads an animation and displays it repeating</li>
|
||||
<li><strong><code>clampAnimMap</code> fps texture texture...:</strong> loads an animation and displays it non-repeating</li>
|
||||
<li><strong><code>mapComp</code> texture:</strong> ???</li>
|
||||
<li><strong><code>mapNoComp</code> texture:</strong> ???</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="In-the-shader-preamble">In the shader preamble:<a href="#In-the-shader-preamble" class="wiki-anchor">¶</a></h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><strong><code>cull none</code>, <code>cull disable</code>, <code>cull twosided</code>:</strong> treat the surface as two sided for lighting</li>
|
||||
<li><strong><code>damageShader</code> shadername:</strong> sets the given shader as damage shader (for SoF2 mods)</li>
|
||||
<li><strong><code>fogparms</code> ...:</strong> marks the brush as a fog volume; otherwise handled by the engine</li>
|
||||
<li><strong><code>implicitBlend</code>:</strong> ???</li>
|
||||
<li><strong><code>implicitMap</code>:</strong> ???</li>
|
||||
<li><strong><code>implicitMask</code>:</strong> ???</li>
|
||||
<li><strong><code>light</code> shadername:</strong> sets the given shader as flare shader</li>
|
||||
<li><strong><code>polygonoffset</code>:</strong> enable polygon offset</li>
|
||||
<li><strong><code>q3map_backShader</code> shadername:</strong> sets the given shader as shader for back faces</li>
|
||||
<li><strong><code>q3map_backsplash</code> percent distance:</strong> configures light backsplash (self-surfacelight)</li>
|
||||
<li><strong><code>q3map_baseShader</code> shadername:</strong> inherit parameters from a shader</li>
|
||||
<li><strong><code>q3map_bounce</code> F, <code>q3map_bounceScale</code> F:</strong> scales the intensity of radiosity</li>
|
||||
<li><strong><code>q3map_clipmodel</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_cloneShader</code> shadername:</strong> ???</li>
|
||||
<li><strong><code>q3map_colorGen</code>:</strong> FIXME later</li>
|
||||
<li><strong><code>q3map_deprecateShader</code> shadername:</strong> ???</li>
|
||||
<li><strong><code>q3map_flare</code> shadername, <code>q3map_flareShader</code> shadername:</strong> sets the given shader as flare shader</li>
|
||||
<li><strong><code>q3map_floodLight</code> r g b dist intensity power:</strong> overrides the global floodlight parameters</li>
|
||||
<li><strong><code>q3map_fogDir</code> ( x y z ):</strong> sets the direction a fog shader fades from transparent to opaque</li>
|
||||
<li><strong><code>q3map_foliage</code> path scale density odds invertalpha:</strong> ???</li>
|
||||
<li><strong><code>q3map_forceMeta</code>:</strong> forces brush faces and/or triangle models to go through the metasurface pipeline</li>
|
||||
<li><strong><code>q3map_forceSunlight</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_fur</code> layers offset fade:</strong> ???</li>
|
||||
<li><strong><code>q3map_globaltexture</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_indexed</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_invert</code>:</strong> inverts the direction from which the face is visible</li>
|
||||
<li><strong><code>q3map_lightRGB</code> r g b:</strong> overrides the light color of the texture</li>
|
||||
<li><strong><code>q3map_lightStyle</code> N:</strong> sets the light style (SoF2, JK2)</li>
|
||||
<li><strong><code>q3map_lightSubdivide</code> N:</strong> subdivision interval for <code>q3map_surfacelight</code></li>
|
||||
<li><strong><code>q3map_lightmapAxis</code> axis:</strong> sets the lightmap axis to one of <code>x</code>, <code>y</code>, <code>z</code> (useful for terrain)</li>
|
||||
<li><strong><code>q3map_lightmapBrightness</code> F, <code>q3map_lightmapGamma</code> F:</strong> overrides lightmap brightness</li>
|
||||
<li><strong><code>q3map_lightmapFilterRadius</code> self other:</strong> ???</li>
|
||||
<li><strong><code>q3map_lightmapMergable</code>:</strong> allows merging the lightmap with other surfaces on another plane</li>
|
||||
<li><strong><code>q3map_lightmapSampleOffset</code> F:</strong> multiplies samplesize by a factor</li>
|
||||
<li><strong><code>q3map_lightmapSampleSize</code> N:</strong> overrides samplesize</li>
|
||||
<li><strong><code>q3map_lightmapSize</code> N:</strong> overrides the lightmap size (forces an external lightmap for this surface)</li>
|
||||
<li><strong><code>q3map_material</code> materialname:</strong> ???</li>
|
||||
<li><strong><code>q3map_noFast</code>:</strong> disable <code>-fast</code> style lighting for this surface</li>
|
||||
<li><strong><code>q3map_noVertexLight</code>:</strong> turns off vertex lighting for this surface</li>
|
||||
<li><strong><code>q3map_noVertexShadows</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_noclip</code>:</strong> do not clip the surface by the BSP tree</li>
|
||||
<li><strong><code>q3map_nofog</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_nonplanar</code>:</strong> marks the surface as nonplanar for meta surface merging</li>
|
||||
<li><strong><code>q3map_notjunc</code>:</strong> do not do t-junction elimination</li>
|
||||
<li><strong><code>q3map_offset</code> F:</strong> ???</li>
|
||||
<li><strong><code>q3map_onlyVertexLighting</code>:</strong> same as using <code>surfaceparm pointlight</code></li>
|
||||
<li><strong><code>q3map_patchShadows</code>:</strong> force shadowing from patches using this shader</li>
|
||||
<li><strong><code>q3map_remapShader</code> shadername:</strong> ???</li>
|
||||
<li><strong><code>q3map_shadeAngle</code> F:</strong> sets the shading angle for nonplanar surfaces</li>
|
||||
<li><strong><code>q3map_skyLight</code> value iterations:</strong> sets the amount of sky light from this surface</li>
|
||||
<li><strong><code>q3map_splotchfix</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_styleMarker2</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_styleMarker</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_sunext</code> r g b intensity degrees elevation deviance samples:</strong> sets an unsharp sun for the map</li>
|
||||
<li><strong><code>q3map_sun</code> r g b intensity degrees elevation, <code>sun</code> r g b intensity degrees elevation:</strong> sets a sharp sun for the map</li>
|
||||
<li><strong><code>q3map_surfacelight</code> F:</strong> sets the amount of surface light from this surface</li>
|
||||
<li><strong><code>q3map_surfacemodel</code> path density minscale maxscale minangle maxangle oriented:</strong> randomly place models on the surface</li>
|
||||
<li><strong><code>q3map_tcGen ivector</code> ( sx sy sz ) ( tx ty tz ):</strong> same as <code>q3map_tcGen vector</code> but with inverted values</li>
|
||||
<li><strong><code>q3map_tcGen vector</code> ( sx sy sz ) ( tx ty tz ):</strong> overrides texcoords based on world coordinates (for terrain)</li>
|
||||
<li><strong><code>q3map_tcMod rotate</code> a:</strong> rotates the texture</li>
|
||||
<li><strong><code>q3map_tcMod scale</code> s t:</strong> multiplies texcoords by factors</li>
|
||||
<li><strong><code>q3map_tcMod translate</code> s t:</strong> translates texcoords by a vector</li>
|
||||
<li><strong><code>q3map_terrain</code>:</strong> ???</li>
|
||||
<li><strong><code>q3map_textureSize</code> width height:</strong> overrides the texture size for texcoords</li>
|
||||
<li><strong><code>q3map_vertexScale</code> F:</strong> scales vertex lighting amount by a factor</li>
|
||||
<li><strong><code>q3map_vertexShadows</code>:</strong> ???</li>
|
||||
<li><strong><code>qer_editorImage</code> texture:</strong> sets the texture to show for radiant</li>
|
||||
<li><strong><code>qer_lightImage</code> texture:</strong> sets the image to take the light color from</li>
|
||||
<li><strong><code>qer_normalImage</code> texture:</strong> sets the normal map for bump mapping</li>
|
||||
<li><strong><code>skyparms</code> outerimage cloudheight innerimage:</strong> loads a skybox</li>
|
||||
<li><strong><code>surfaceparm</code> alphashadow:</strong> use the alpha channel of the shader image as shadow mask</li>
|
||||
<li><strong><code>surfaceparm</code> areaportal:</strong> ???</li>
|
||||
<li><strong><code>surfaceparm</code> botclip:</strong> ???</li>
|
||||
<li><strong><code>surfaceparm</code> clusterportal:</strong> ???</li>
|
||||
<li><strong><code>surfaceparm</code> detail:</strong> ignore this surface for vis</li>
|
||||
<li><strong><code>surfaceparm</code> donotenter:</strong> ???</li>
|
||||
<li><strong><code>surfaceparm</code> fog:</strong> ???</li>
|
||||
<li><strong><code>surfaceparm</code> hint:</strong> use this surface as a hint to generate BSP splits</li>
|
||||
<li><strong><code>surfaceparm</code> lava:</strong> Stef hates this brush</li>
|
||||
<li><strong><code>surfaceparm</code> lightfilter:</strong> use the color channel of the shader image as shadow mask</li>
|
||||
<li><strong><code>surfaceparm</code> monsterclip:</strong> monsters can't go through this brush, but shots can</li>
|
||||
<li><strong><code>surfaceparm</code> nodraw:</strong> do not generate draw surfaces</li>
|
||||
<li><strong><code>surfaceparm</code> nodrop:</strong> items can't be dropped on this brush</li>
|
||||
<li><strong><code>surfaceparm</code> nolightmap, <code>surfaceparm</code> pointlight:</strong> do not lightmap this surface</li>
|
||||
<li><strong><code>surfaceparm</code> nomarks:</strong> this surface is stain free</li>
|
||||
<li><strong><code>surfaceparm</code> nonsolid:</strong> do not make this surface solid</li>
|
||||
<li><strong><code>surfaceparm</code> origin:</strong> the center of this brush shall be the origin of this brush model</li>
|
||||
<li><strong><code>surfaceparm</code> playerclip:</strong> players can't go through this brush, but shots can</li>
|
||||
<li><strong><code>surfaceparm</code> sky:</strong> this surface shows the skybox</li>
|
||||
<li><strong><code>surfaceparm</code> slime:</strong> this brush contains more poisonous stuff than dihydrogene monoxide</li>
|
||||
<li><strong><code>surfaceparm</code> structural:</strong> use this surface for vis</li>
|
||||
<li><strong><code>surfaceparm</code> trans:</strong> cast no shadows</li>
|
||||
<li><strong><code>surfaceparm</code> trigger:</strong> this is a trigger brush (translucent and solid)</li>
|
||||
<li><strong><code>surfaceparm</code> water:</strong> this brush contains dihydrogene monoxide</li>
|
||||
<li><strong><code>tessSize</code> F, <code>q3map_tessSize</code> F:</strong> subdivides the polygons to ensure no parts are larger than the given size</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="other-formats">Экспортировать в
|
||||
<span><a href="/projects/netradiant/wiki/Complete_list_of_shader_keywords?format=html&version=1" class="html" rel="nofollow">HTML</a></span>
|
||||
<span><a href="/projects/netradiant/wiki/Complete_list_of_shader_keywords?format=txt&version=1" class="txt" rel="nofollow">TXT</a></span>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span>Загрузка...</span></div>
|
||||
|
||||
<div id="footer">
|
||||
Powered by <a href="http://www.redmine.org/">Redmine</a> © 2006-2010 Jean-Philippe Lang
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
881
docs/application.css
Normal file
|
|
@ -0,0 +1,881 @@
|
|||
body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
|
||||
|
||||
h1, h2, h3, h4 { font-family: "Trebuchet MS", Verdana, sans-serif;}
|
||||
h1 {margin:0; padding:0; font-size: 24px;}
|
||||
h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
|
||||
h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
|
||||
h4, .wiki h3 {font-size: 13px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb; color: #444;}
|
||||
|
||||
/***** Layout *****/
|
||||
#wrapper {background: white;}
|
||||
|
||||
#top-menu {background: #55646D; color: #fff; height:2em; font-size: 0.8em; padding: 4px 2px 0px 6px;border-bottom:2px solid #333}
|
||||
#top-menu ul {margin: 0; padding: 0;}
|
||||
#top-menu li {
|
||||
float:left;
|
||||
list-style-type:none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
white-space:nowrap;
|
||||
}
|
||||
#top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
|
||||
#top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; margin-top:2px; }
|
||||
|
||||
#top-menu ul a { padding:2px 0 3px 20px; display:block; height:16px; }
|
||||
#top-menu a.home { background:transparent url('house.png') 0 0 no-repeat; }
|
||||
#top-menu a.my-page { background:transparent url('../images/my-page.png') 0 0 no-repeat; }
|
||||
#top-menu a.projects { background:transparent url('projects.png') 0 0 no-repeat; }
|
||||
#top-menu a.stuff-to-do { background:transparent url('../images/stuff_to_do.png') 0 0 no-repeat; }
|
||||
#top-menu a.timesheet { background:transparent url('../images/timesheet.png') 0 0 no-repeat; }
|
||||
#top-menu a.administration { background:transparent url('../images/administration.png') 0 0 no-repeat; }
|
||||
#top-menu a.help { background:transparent url('help-top.png') 0 0 no-repeat; }
|
||||
#top-menu a.logout { background:transparent url('../images/sign-out.png') 0 0 no-repeat; }
|
||||
#top-menu a.my-account { background:transparent url('../images/my-account.png') 0 0 no-repeat; }
|
||||
|
||||
#account {float:right;}
|
||||
|
||||
#header {height:5.3em;margin:0;background:#547938 url('header_gradient.png') 0 0 repeat-x;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;}
|
||||
#header a {color:#f8f8f8;}
|
||||
#header h1 { float:left; margin-top:5px; }
|
||||
#header h1 a.ancestor { font-size: 80%; }
|
||||
#quick-search {float:right;}
|
||||
|
||||
#main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px; }
|
||||
#main-menu ul {margin: 0; padding: 0;}
|
||||
#main-menu li {
|
||||
float:left;
|
||||
list-style-type:none;
|
||||
margin: 0px 2px 0px 0px;
|
||||
padding: 0px 0px 0px 0px;
|
||||
white-space:nowrap;
|
||||
}
|
||||
#main-menu li a {
|
||||
display: block;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 4px 10px 4px 26px;
|
||||
background-position:6px center;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
#main-menu li a:hover {
|
||||
background:#8ACB58;
|
||||
color:#fff;
|
||||
background-position:6px center;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
#main-menu li a.selected, #main-menu li a.selected:hover {
|
||||
background-color:#fff;
|
||||
color:#555;
|
||||
background-position:6px center;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
|
||||
/* Redmine core project-menu links */
|
||||
#main-menu li a.overview { background-image: url(document-text-image.png); }
|
||||
#main-menu li a.activity { background-image: url(lightning.png); }
|
||||
#main-menu li a.roadmap { background-image: url(../images/fugue/map-pin.png); }
|
||||
#main-menu li a.issues { background-image: url(ticket.png); }
|
||||
#main-menu li a.new-issue { background-image: url(../images/fugue/ticket--plus.png); }
|
||||
#main-menu li a.news { background-image: url(newspaper.png); }
|
||||
#main-menu li a.documents { background-image: url(documents-text.png); }
|
||||
#main-menu li a.wiki { background-image: url(document-horizontal-text.png); }
|
||||
#main-menu li a.boards { background-image: url(balloons.png); }
|
||||
#main-menu li a.files { background-image: url(document-zipper.png); }
|
||||
#main-menu li a.repository { background-image: url(safe.png); }
|
||||
#main-menu li a.customers { background-image: url(../images/fugue/user-business.png); }
|
||||
#main-menu li a.ezfaq { background-image: url(help-top.png); }
|
||||
#main-menu li a.settings { background-image: url(../images/fugue/equalizer.png); }
|
||||
|
||||
#main {background-color:#EEEEEE;}
|
||||
|
||||
#sidebar{ float: right; width: 17%; position: relative; z-index: 9; min-height: 600px; padding: 0; margin: 0;}
|
||||
* html #sidebar{ width: 17%; }
|
||||
#sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
|
||||
#sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
|
||||
* html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
|
||||
|
||||
#content { width: 80%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
|
||||
* html #content{ width: 80%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
|
||||
html>body #content { min-height: 600px; }
|
||||
* html body #content { height: 600px; } /* IE */
|
||||
|
||||
#main.nosidebar #sidebar{ display: none; }
|
||||
#main.nosidebar #content{ width: auto; border-right: 0; }
|
||||
|
||||
#footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
|
||||
|
||||
#login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
|
||||
#login-form table td {padding: 6px;}
|
||||
#login-form label {font-weight: bold;}
|
||||
#login-form input#username, #login-form input#password { width: 300px; }
|
||||
|
||||
input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; }
|
||||
|
||||
.clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
|
||||
|
||||
/***** Links *****/
|
||||
a, a:link, a:visited{ color: #3F794B; text-decoration: none; }
|
||||
a:hover, a:active{ color: #3A4F5B; text-decoration: underline;}
|
||||
a img{ border: 0; }
|
||||
|
||||
a.issue.closed, a.issue.closed:link, a.issue.closed:visited { text-decoration: line-through; }
|
||||
|
||||
/***** Tables *****/
|
||||
table.list { border: 1px solid #49702A; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
|
||||
table.list th { background:#547938 url('header_gradient.png') 0 0 repeat-x; color:#D6E4CB; padding: 4px; white-space:nowrap; }
|
||||
table.list th a { color:#fff; }
|
||||
table.list th a:hover { color:#E0FFC9; }
|
||||
table.list td { vertical-align: top; }
|
||||
table.list td.id { width: 2%; text-align: center;}
|
||||
table.list td.checkbox { width: 15px; padding: 0px;}
|
||||
table.list.issues .status-1 .id { background:transparent url('../images/new.png') center 18px no-repeat; }
|
||||
table.list.issues .status-2 .id { background:transparent url('../images/assigned.png') center 18px no-repeat; }
|
||||
table.list.issues .status-3 .id { background:transparent url('../images/resolved.png') center 18px no-repeat; }
|
||||
table.list.issues .status-4 .id { background:transparent url('../images/feedback.png') center 18px no-repeat; }
|
||||
table.list.issues .status-5 .id { background:transparent url('../images/closed.png') center 18px no-repeat; }
|
||||
table.list.issues .status-6 .id { background:transparent url('../images/rejected.png') center 18px no-repeat; }
|
||||
table.list.issues .status-8 .id { background:transparent url('../images/waiting.png') center 18px no-repeat; }
|
||||
table.list.issues .status-7 .id { background:transparent url('../images/wont_fix.png') center 18px no-repeat; }
|
||||
|
||||
tr.issue { text-align: center; white-space: nowrap; }
|
||||
tr.issue td.subject, tr.issue td.category, td.assigned_to { white-space: normal; }
|
||||
tr.issue td.subject { text-align: left; }
|
||||
tr.issue td.done_ratio { width:80px }
|
||||
tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
|
||||
|
||||
tr.priority-1.even { background-color:#F8FFAA; }
|
||||
tr.priority-1.odd { background-color:#FAFFB8; }
|
||||
tr.priority-2.even { background-color:#FFEF9A; }
|
||||
tr.priority-2.odd { background-color:#FFF1A6; }
|
||||
tr.priority-3.even { background-color:#FFD29A; }
|
||||
tr.priority-3.odd { background-color:#FFD8A6; }
|
||||
tr.priority-4.even { background-color:#FFB19A; }
|
||||
tr.priority-4.odd { background-color:#FFBAA6; }
|
||||
tr.priority-5.even { background-color:#FF9A9F; }
|
||||
tr.priority-5.odd { background-color:#FFA6AA; }
|
||||
|
||||
.status { text-align:left; padding-left:22px; }
|
||||
tr.status-1 .status { background:transparent url('../images/new.png') 0 0 no-repeat; }
|
||||
tr.status-2 .status { background:transparent url('../images/assigned.png') 0 0 no-repeat; }
|
||||
tr.status-3 .status { background:transparent url('../images/resolved.png') 0 0 no-repeat; }
|
||||
tr.status-4 .status { background:transparent url('../images/feedback.png') 0 0 no-repeat; }
|
||||
tr.status-5 .status { background:transparent url('../images/closed.png') 0 0 no-repeat; }
|
||||
tr.status-6 .status { background:transparent url('../images/rejected.png') 0 0 no-repeat; }
|
||||
tr.status-8 .status { background:transparent url('../images/waiting.png') 0 0 no-repeat; }
|
||||
tr.status-7 .status { background:transparent url('../images/wont_fix.png') 0 0 no-repeat; }
|
||||
|
||||
tr.entry { border: 1px solid #f8f8f8; }
|
||||
tr.entry td { white-space: nowrap; }
|
||||
tr.entry td.filename { width: 30%; }
|
||||
tr.entry td.size { text-align: right; font-size: 90%; }
|
||||
tr.entry td.revision, tr.entry td.author { text-align: center; }
|
||||
tr.entry td.age { text-align: right; }
|
||||
|
||||
tr.entry span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
|
||||
tr.entry.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
|
||||
tr.entry.file td.filename a { margin-left: 16px; }
|
||||
tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
|
||||
tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
|
||||
|
||||
tr.changeset td.author { text-align: center; width: 15%; }
|
||||
tr.changeset td.committed_on { text-align: center; width: 15%; }
|
||||
|
||||
table.files tr.file td { text-align: center; }
|
||||
table.files tr.file td.filename { text-align: left; padding-left: 24px; }
|
||||
table.files tr.file td.digest { font-size: 80%; }
|
||||
|
||||
table.members td.roles, table.memberships td.roles { width: 45%; }
|
||||
|
||||
tr.message { height: 2.6em; }
|
||||
tr.message td.last_message { font-size: 80%; }
|
||||
tr.message.locked td.subject a { background-image: url(../images/locked.png); }
|
||||
tr.message.sticky td.subject a { background-image: url(../images/sticky.png); font-weight: bold; }
|
||||
|
||||
tr.user td { width:13%; }
|
||||
tr.user td.email { width:18%; }
|
||||
tr.user td { white-space: nowrap; }
|
||||
tr.user.locked, tr.user.registered { color: #aaa; }
|
||||
tr.user.locked a, tr.user.registered a { color: #aaa; }
|
||||
|
||||
tr.time-entry { text-align: center; white-space: nowrap; }
|
||||
tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; white-space: normal; }
|
||||
td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
|
||||
td.hours .hours-dec { font-size: 0.9em; }
|
||||
|
||||
table.plugins td { vertical-align: middle; }
|
||||
table.plugins td.configure { text-align: right; padding-right: 1em; }
|
||||
table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
|
||||
table.plugins span.description { display: block; font-size: 0.9em; }
|
||||
table.plugins span.url { display: block; font-size: 0.9em; }
|
||||
|
||||
table.list tbody tr.group td { padding: 0.8em 0 0.5em 0.3em; font-weight: bold; border-bottom: 1px solid #ccc; }
|
||||
table.list tbody tr.group span.count { color: #aaa; font-size: 80%; }
|
||||
|
||||
table.list tbody tr:hover { background-color:#ffffdd; }
|
||||
table.list tbody tr.group:hover { background-color:inherit; }
|
||||
table td {padding:2px;}
|
||||
table p {margin:0;}
|
||||
.odd {background-color:#f6f7f8;}
|
||||
.even {background-color: #fff;}
|
||||
a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; }
|
||||
a.sort.asc { background-image: url(../images/sort_asc.png); }
|
||||
a.sort.desc { background-image: url(../images/sort_desc.png); }
|
||||
|
||||
table.attributes { width: 100% }
|
||||
table.attributes th { vertical-align: top; text-align: left; }
|
||||
table.attributes td { vertical-align: top; }
|
||||
|
||||
td.center {text-align:center;}
|
||||
|
||||
.highlight { background-color: #FCFD8D;}
|
||||
.highlight.token-1 { background-color: #faa;}
|
||||
.highlight.token-2 { background-color: #afa;}
|
||||
.highlight.token-3 { background-color: #aaf;}
|
||||
|
||||
.box{
|
||||
padding:6px;
|
||||
margin-bottom: 10px;
|
||||
background-color:#f6f6f6;
|
||||
color:#505050;
|
||||
line-height:1.5em;
|
||||
border: 1px solid #e4e4e4;
|
||||
}
|
||||
|
||||
div.square {
|
||||
border: 1px solid #999;
|
||||
float: left;
|
||||
margin: .3em .4em 0 .4em;
|
||||
overflow: hidden;
|
||||
width: .6em; height: .6em;
|
||||
}
|
||||
.contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
|
||||
.contextual input, .contextual select {font-size:0.9em;}
|
||||
.message .contextual { margin-top: 0; }
|
||||
|
||||
.splitcontentleft{float:left; width:49%;}
|
||||
.splitcontentright{float:right; width:49%;}
|
||||
form {display: inline;}
|
||||
input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
|
||||
fieldset {border: 1px solid #e4e4e4; margin:0;}
|
||||
legend {color: #484848;}
|
||||
hr { width: 100%; height: 1px; background: #ccc; border: 0;}
|
||||
blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
|
||||
blockquote blockquote { margin-left: 0;}
|
||||
textarea.wiki-edit { width: 99%; }
|
||||
li p {margin-top: 0;}
|
||||
div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
|
||||
p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
|
||||
p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
|
||||
p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
|
||||
|
||||
fieldset.collapsible { border-width: 1px 0 0 0; font-size: 0.9em; }
|
||||
fieldset.collapsible legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
|
||||
fieldset.collapsible.collapsed legend { background-image: url(../images/arrow_collapsed.png); }
|
||||
|
||||
fieldset#date-range p { margin: 2px 0 2px 0; }
|
||||
fieldset#filters table { border-collapse: collapse; }
|
||||
fieldset#filters table td { padding: 0; vertical-align: middle; }
|
||||
fieldset#filters tr.filter { height: 2em; }
|
||||
fieldset#filters td.add-filter { text-align: right; vertical-align: top; }
|
||||
.buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; }
|
||||
|
||||
div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
|
||||
div#issue-changesets .changeset { padding: 4px;}
|
||||
div#issue-changesets .changeset { border-bottom: 1px solid #ddd; }
|
||||
div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
|
||||
|
||||
div#activity dl, #search-results { margin-left: 2em; }
|
||||
div#activity dd, #search-results dd { margin-bottom: 1em; padding:4px; font-size: 0.9em; background-color:#eee; border:1px solid #ddd; border-top:0; }
|
||||
div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
|
||||
div#activity dt.me .time { border-bottom: 1px solid #999; }
|
||||
div#activity dt .time { color: #777; font-size: 80%; }
|
||||
div#activity dd .description, #search-results dd .description { font-style: italic; }
|
||||
div#activity span.project:after, #search-results span.project:after { content: " -"; }
|
||||
div#activity dd span.description, #search-results dd span.description { display:block; }
|
||||
|
||||
#search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
|
||||
div#search-results-counts {float:right;}
|
||||
div#search-results-counts ul { margin-top: 0.5em; }
|
||||
div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
|
||||
|
||||
dt.me a { background:transparent url(../images/fav.png) right 0 no-repeat; padding-right:18px; }
|
||||
dt.issue { background-image: url(../images/ticket.png); background-color:#fed; border:1px solid #edc; }
|
||||
dt.issue-edit { background-image: url(../images/ticket_edit.png); background-color:#fdf; border:1px solid #ece; }
|
||||
dt.issue-closed { background-image: url(../images/ticket_checked.png); background-color:#ddf; border:1px solid #cce; }
|
||||
dt.issue-note { background-image: url(../images/ticket_note.png); background-color:#ffd; border:1px solid #eec; }
|
||||
dt.changeset { background-image: url(../images/changeset.png); background-color:#dfd; border:1px solid #cec; }
|
||||
dt.news { background-image: url(../images/news.png); }
|
||||
dt.message { background-image: url(../images/message.png); }
|
||||
dt.reply { background-image: url(../images/comments.png); }
|
||||
dt.wiki-page { background-image: url(../images/wiki_edit.png); }
|
||||
dt.attachment { background-image: url(attachment.png); }
|
||||
dt.document { background-image: url(../images/document.png); }
|
||||
dt.project { background-image: url(projects.png); }
|
||||
dt.time-entry { background-image: url(../images/time.png); }
|
||||
|
||||
#search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
|
||||
|
||||
div#roadmap fieldset.related-issues { margin-bottom: 1em; }
|
||||
div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; }
|
||||
div#roadmap .wiki h1:first-child { display: none; }
|
||||
div#roadmap .wiki h1 { font-size: 120%; }
|
||||
div#roadmap .wiki h2 { font-size: 110%; }
|
||||
|
||||
div#version-summary { float:right; width:380px; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
|
||||
div#version-summary fieldset { margin-bottom: 1em; }
|
||||
div#version-summary .total-hours { text-align: right; }
|
||||
|
||||
table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
|
||||
table#time-report tbody tr { font-style: italic; color: #777; }
|
||||
table#time-report tbody tr.last-level { font-style: normal; color: #555; }
|
||||
table#time-report tbody tr.total { font-style: normal; font-weight: bold; color: #555; background-color:#EEEEEE; }
|
||||
table#time-report .hours-dec { font-size: 0.9em; }
|
||||
|
||||
form#issue-form .attributes { margin-bottom: 8px; }
|
||||
form#issue-form .attributes p { padding-top: 1px; padding-bottom: 2px; }
|
||||
form#issue-form .attributes select { min-width: 30%; }
|
||||
|
||||
ul.projects { margin: 0; padding-left: 1em; }
|
||||
ul.projects.root { margin: 0; padding: 0; }
|
||||
ul.projects ul { border-left: 3px solid #e0e0e0; }
|
||||
ul.projects li { list-style-type:none; }
|
||||
ul.projects li.root { margin-bottom: 1em; }
|
||||
ul.projects li.child { margin-top: 1em;}
|
||||
ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
|
||||
.my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
|
||||
|
||||
#tracker_project_ids ul { margin: 0; padding-left: 1em; }
|
||||
#tracker_project_ids li { list-style-type:none; }
|
||||
|
||||
ul.properties {padding:0; font-size: 0.9em; color: #777;}
|
||||
ul.properties li {list-style-type:none;}
|
||||
ul.properties li span {font-style:italic;}
|
||||
|
||||
.total-hours { font-size: 110%; font-weight: bold; }
|
||||
.total-hours span.hours-int { font-size: 120%; }
|
||||
|
||||
.autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;}
|
||||
#user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
|
||||
|
||||
.pagination {font-size: 90%}
|
||||
p.pagination {margin-top:8px;}
|
||||
|
||||
/***** Tabular forms ******/
|
||||
.tabular p{
|
||||
margin: 0;
|
||||
padding: 5px 0 8px 0;
|
||||
padding-left: 180px; /*width of left column containing the label elements*/
|
||||
height: 1%;
|
||||
clear:left;
|
||||
}
|
||||
|
||||
html>body .tabular p {overflow:hidden;}
|
||||
|
||||
.tabular label{
|
||||
font-weight: bold;
|
||||
float: left;
|
||||
text-align: right;
|
||||
margin-left: -180px; /*width of left column*/
|
||||
width: 175px; /*width of labels. Should be smaller than left column to create some right
|
||||
margin*/
|
||||
}
|
||||
|
||||
.tabular label.floating{
|
||||
font-weight: normal;
|
||||
margin-left: 0px;
|
||||
text-align: left;
|
||||
width: 270px;
|
||||
}
|
||||
|
||||
.tabular label.block{
|
||||
font-weight: normal;
|
||||
margin-left: 0px;
|
||||
text-align: left;
|
||||
float: none;
|
||||
display: block;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
input#time_entry_comments { width: 90%;}
|
||||
|
||||
#preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
|
||||
|
||||
.tabular.settings p{ padding-left: 300px; }
|
||||
.tabular.settings label{ margin-left: -300px; width: 295px; }
|
||||
|
||||
.required {color: #bb0000;}
|
||||
.summary {font-style: italic;}
|
||||
|
||||
#attachments_fields input[type=text] {margin-left: 8px; }
|
||||
|
||||
div.attachments { margin-top: 12px; }
|
||||
div.attachments p { margin:4px 0 2px 0; }
|
||||
div.attachments img { vertical-align: middle; }
|
||||
div.attachments span.author { font-size: 0.9em; color: #888; }
|
||||
|
||||
p.other-formats { text-align: right; font-size:0.9em; color: #666; }
|
||||
.other-formats span + span:before { content: "| "; }
|
||||
|
||||
a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
|
||||
|
||||
/* Project members tab */
|
||||
div#tab-content-members .splitcontentleft, div#tab-content-memberships .splitcontentleft, div#tab-content-users .splitcontentleft { width: 64% }
|
||||
div#tab-content-members .splitcontentright, div#tab-content-memberships .splitcontentright, div#tab-content-users .splitcontentright { width: 34% }
|
||||
div#tab-content-members fieldset, div#tab-content-memberships fieldset, div#tab-content-users fieldset { padding:1em; margin-bottom: 1em; }
|
||||
div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; }
|
||||
div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; }
|
||||
div#tab-content-members fieldset div, div#tab-content-users fieldset div { max-height: 400px; overflow:auto; }
|
||||
|
||||
table.members td.group { padding-left: 20px; background: url(../images/users.png) no-repeat 0% 0%; }
|
||||
|
||||
* html div#tab-content-members fieldset div { height: 450px; }
|
||||
|
||||
/***** Flash & error messages ****/
|
||||
#errorExplanation, div.flash, .nodata, .warning {
|
||||
padding: 4px 4px 4px 30px;
|
||||
margin-bottom: 12px;
|
||||
font-size: 1.1em;
|
||||
border: 2px solid;
|
||||
}
|
||||
|
||||
div.flash {margin-top: 8px;}
|
||||
|
||||
div.flash.error, #errorExplanation {
|
||||
background: url(../images/false.png) 8px 5px no-repeat;
|
||||
background-color: #ffe3e3;
|
||||
border-color: #dd0000;
|
||||
color: #550000;
|
||||
}
|
||||
|
||||
div.flash.notice {
|
||||
background: url(../images/true.png) 8px 5px no-repeat;
|
||||
background-color: #dfffdf;
|
||||
border-color: #9fcf9f;
|
||||
color: #005f00;
|
||||
}
|
||||
|
||||
div.flash.warning {
|
||||
background: url(../images/warning.png) 8px 5px no-repeat;
|
||||
background-color: #FFEBC1;
|
||||
border-color: #FDBF3B;
|
||||
color: #A6750C;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.nodata, .warning {
|
||||
text-align: center;
|
||||
background-color: #FFEBC1;
|
||||
border-color: #FDBF3B;
|
||||
color: #A6750C;
|
||||
}
|
||||
|
||||
#errorExplanation ul { font-size: 0.9em;}
|
||||
#errorExplanation h2, #errorExplanation p { display: none; }
|
||||
|
||||
/***** Ajax indicator ******/
|
||||
#ajax-indicator {
|
||||
position: absolute; /* fixed not supported by IE */
|
||||
background-color:#eee;
|
||||
border: 1px solid #bbb;
|
||||
top:35%;
|
||||
left:40%;
|
||||
width:20%;
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
padding:0.6em;
|
||||
z-index:100;
|
||||
filter:alpha(opacity=50);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
html>body #ajax-indicator { position: fixed; }
|
||||
|
||||
#ajax-indicator span {
|
||||
background-position: 0% 40%;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url(../images/loading.gif);
|
||||
padding-left: 26px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
/***** Calendar *****/
|
||||
table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
|
||||
table.cal thead th {width: 14%;}
|
||||
table.cal tbody tr {height: 100px;}
|
||||
table.cal th { background-color:#EEEEEE; padding: 4px; }
|
||||
table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
|
||||
table.cal td p.day-num {font-size: 1.1em; text-align:right;}
|
||||
table.cal td.odd p.day-num {color: #bbb;}
|
||||
table.cal td.today {background:#ffffdd;}
|
||||
table.cal td.today p.day-num {font-weight: bold;}
|
||||
|
||||
/***** Tooltips ******/
|
||||
.tooltip{position:relative;z-index:24;}
|
||||
.tooltip:hover{z-index:25;color:#000;}
|
||||
.tooltip span.tip{display: none; text-align:left;}
|
||||
|
||||
div.tooltip:hover span.tip{
|
||||
display:block;
|
||||
position:absolute;
|
||||
top:12px; left:24px; width:270px;
|
||||
border:1px solid #555;
|
||||
background-color:#fff;
|
||||
padding: 4px;
|
||||
font-size: 0.8em;
|
||||
color:#505050;
|
||||
}
|
||||
|
||||
/***** Progress bar *****/
|
||||
table.progress {
|
||||
border: 1px solid #D7D7D7;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0pt;
|
||||
empty-cells: show;
|
||||
text-align: center;
|
||||
float:left;
|
||||
margin: 1px 6px 1px 0px;
|
||||
}
|
||||
|
||||
table.progress td { height: 0.9em; }
|
||||
table.progress td.todo { border:1px solid #aaa }
|
||||
table.progress td.closed { background: #648749 none repeat scroll 0%; }
|
||||
table.progress td.done { background: #DEF0DE none repeat scroll 0%; }
|
||||
table.progress td.open { background: #FFF none repeat scroll 0%; }
|
||||
p.pourcent {font-size: 80%;}
|
||||
p.progress-info {clear: left; font-style: italic; font-size: 80%;}
|
||||
|
||||
/***** Tabs *****/
|
||||
#content .tabs {height: 2.6em; border-bottom: 1px solid #bbbbbb; margin-bottom:1.2em; position:relative;}
|
||||
#content .tabs ul {margin:0; position:absolute; bottom:-2px; padding-left:1em;}
|
||||
#content .tabs>ul { bottom:-1px; } /* others */
|
||||
#content .tabs ul li {
|
||||
float:left;
|
||||
list-style-type:none;
|
||||
white-space:nowrap;
|
||||
margin-right:8px;
|
||||
background:#fff;
|
||||
}
|
||||
#content .tabs ul li a{
|
||||
display:block;
|
||||
font-size: 0.9em;
|
||||
text-decoration:none;
|
||||
line-height:1.3em;
|
||||
padding:4px 6px 4px 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-bottom: 1px solid #bbbbbb;
|
||||
background-color: #eeeeee;
|
||||
color:#777;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#content .tabs ul li a:hover {
|
||||
background-color: #ffffdd;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
#content .tabs ul li a.selected {
|
||||
background-color: #fff;
|
||||
border: 1px solid #bbbbbb;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
#content .tabs ul li a.selected:hover {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/***** Auto-complete *****/
|
||||
div.autocomplete {
|
||||
position:absolute;
|
||||
width:250px;
|
||||
background-color:white;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
div.autocomplete ul {
|
||||
list-style-type:none;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
div.autocomplete ul li.selected { background-color: #ffb;}
|
||||
div.autocomplete ul li {
|
||||
list-style-type:none;
|
||||
display:block;
|
||||
margin:0;
|
||||
padding:2px;
|
||||
cursor:pointer;
|
||||
font-size: 90%;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-left: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
div.autocomplete ul li span.informal {
|
||||
font-size: 80%;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
/***** Diff *****/
|
||||
.diff_out { background: #fcc; }
|
||||
.diff_in { background: #cfc; }
|
||||
|
||||
/***** Wiki *****/
|
||||
div.wiki table {
|
||||
border: 1px solid #505050;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div.wiki table, div.wiki td, div.wiki th {
|
||||
border: 1px solid #bbb;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
div.wiki .external {
|
||||
background-position: 0% 60%;
|
||||
background-repeat: no-repeat;
|
||||
padding-left: 12px;
|
||||
background-image: url(external.png);
|
||||
}
|
||||
|
||||
div.wiki a.new {
|
||||
color: #b73535;
|
||||
}
|
||||
|
||||
div.wiki pre {
|
||||
margin: 1em 1em 1em 1.6em;
|
||||
padding: 2px;
|
||||
background-color: #fafafa;
|
||||
border: 1px solid #dadada;
|
||||
width:95%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
div.wiki ul.toc {
|
||||
background-color: #ffffdd;
|
||||
border: 1px solid #e4e4e4;
|
||||
padding: 4px;
|
||||
line-height: 1.2em;
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
margin-left: 0;
|
||||
display: table
|
||||
}
|
||||
* html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
|
||||
|
||||
div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
|
||||
div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
|
||||
div.wiki ul.toc li { list-style-type:none;}
|
||||
div.wiki ul.toc li.heading2 { margin-left: 6px; }
|
||||
div.wiki ul.toc li.heading3 { margin-left: 12px; font-size: 0.8em; }
|
||||
|
||||
div.wiki ul.toc a {
|
||||
font-size: 0.9em;
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
color: #606060;
|
||||
}
|
||||
div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
|
||||
|
||||
a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
|
||||
a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
|
||||
h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
|
||||
|
||||
/***** My page layout *****/
|
||||
.block-receiver {
|
||||
border:1px dashed #c0c0c0;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px 0 15px 0;
|
||||
}
|
||||
|
||||
.mypage-box {
|
||||
margin:0 0 20px 0;
|
||||
color:#505050;
|
||||
line-height:1.5em;
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
a.close-icon {
|
||||
display:block;
|
||||
margin-top:3px;
|
||||
overflow:hidden;
|
||||
width:12px;
|
||||
height:12px;
|
||||
background-repeat: no-repeat;
|
||||
cursor:pointer;
|
||||
background-image:url('../images/close.png');
|
||||
}
|
||||
|
||||
a.close-icon:hover {
|
||||
background-image:url('../images/close_hl.png');
|
||||
}
|
||||
|
||||
/***** Gantt chart *****/
|
||||
.gantt_hdr {
|
||||
position:absolute;
|
||||
top:0;
|
||||
height:16px;
|
||||
border-top: 1px solid #c0c0c0;
|
||||
border-bottom: 1px solid #c0c0c0;
|
||||
border-right: 1px solid #c0c0c0;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.task {
|
||||
position: absolute;
|
||||
height:8px;
|
||||
font-size:0.8em;
|
||||
color:#888;
|
||||
padding:0;
|
||||
margin:0;
|
||||
line-height:0.8em;
|
||||
}
|
||||
|
||||
.task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
|
||||
.task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }
|
||||
.task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
|
||||
.milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
|
||||
|
||||
/***** Icons *****/
|
||||
.icon {
|
||||
background-position: 0% 40%;
|
||||
background-repeat: no-repeat;
|
||||
padding-left: 20px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.icon22 {
|
||||
background-position: 0% 40%;
|
||||
background-repeat: no-repeat;
|
||||
padding-left: 26px;
|
||||
line-height: 22px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.icon-add { background-image: url(../images/add.png); }
|
||||
.icon-edit { background-image: url(../images/edit.png); }
|
||||
.icon-copy { background-image: url(../images/copy.png); }
|
||||
.icon-del { background-image: url(../images/delete.png); }
|
||||
.icon-move { background-image: url(../images/move.png); }
|
||||
.icon-save { background-image: url(../images/save.png); }
|
||||
.icon-cancel { background-image: url(../images/cancel.png); }
|
||||
.icon-file { background-image: url(../images/file.png); }
|
||||
.icon-folder { background-image: url(../images/folder.png); }
|
||||
.open .icon-folder { background-image: url(../images/folder_open.png); }
|
||||
.icon-package { background-image: url(../images/package.png); }
|
||||
.icon-home { background-image: url(../images/home.png); }
|
||||
.icon-user { background-image: url(../images/user.png); }
|
||||
.icon-mypage { background-image: url(../images/user_page.png); }
|
||||
.icon-admin { background-image: url(../images/admin.png); }
|
||||
.icon-projects { background-image: url(projects.png); }
|
||||
.icon-help { background-image: url(../images/help.png); }
|
||||
.icon-attachment { background-image: url(attachment.png); }
|
||||
.icon-index { background-image: url(../images/index.png); }
|
||||
.icon-history { background-image: url(history.png); }
|
||||
.icon-time { background-image: url(../images/time.png); }
|
||||
.icon-time-add { background-image: url(../images/time_add.png); }
|
||||
.icon-stats { background-image: url(../images/stats.png); }
|
||||
.icon-warning { background-image: url(../images/warning.png); }
|
||||
.icon-fav { background-image: url(../images/fav.png); }
|
||||
.icon-fav-off { background-image: url(../images/fav_off.png); }
|
||||
.icon-reload { background-image: url(../images/reload.png); }
|
||||
.icon-lock { background-image: url(../images/locked.png); }
|
||||
.icon-unlock { background-image: url(../images/unlock.png); }
|
||||
.icon-checked { background-image: url(../images/true.png); }
|
||||
.icon-details { background-image: url(../images/zoom_in.png); }
|
||||
.icon-report { background-image: url(../images/report.png); }
|
||||
.icon-comment { background-image: url(../images/comment.png); }
|
||||
|
||||
.icon-file { background-image: url(../images/files/default.png); }
|
||||
.icon-file.text-plain { background-image: url(../images/files/text.png); }
|
||||
.icon-file.text-x-c { background-image: url(../images/files/c.png); }
|
||||
.icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); }
|
||||
.icon-file.text-x-php { background-image: url(../images/files/php.png); }
|
||||
.icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); }
|
||||
.icon-file.text-xml { background-image: url(../images/files/xml.png); }
|
||||
.icon-file.image-gif { background-image: url(../images/files/image.png); }
|
||||
.icon-file.image-jpeg { background-image: url(../images/files/image.png); }
|
||||
.icon-file.image-png { background-image: url(../images/files/image.png); }
|
||||
.icon-file.image-tiff { background-image: url(../images/files/image.png); }
|
||||
.icon-file.application-pdf { background-image: url(../images/files/pdf.png); }
|
||||
.icon-file.application-zip { background-image: url(../images/files/zip.png); }
|
||||
.icon-file.application-x-gzip { background-image: url(../images/files/zip.png); }
|
||||
|
||||
.icon22-projects { background-image: url(../images/22x22/projects.png); }
|
||||
.icon22-users { background-image: url(../images/22x22/users.png); }
|
||||
.icon22-groups { background-image: url(../images/22x22/groups.png); }
|
||||
.icon22-tracker { background-image: url(../images/22x22/tracker.png); }
|
||||
.icon22-role { background-image: url(../images/22x22/role.png); }
|
||||
.icon22-workflow { background-image: url(../images/22x22/workflow.png); }
|
||||
.icon22-options { background-image: url(../images/22x22/options.png); }
|
||||
.icon22-notifications { background-image: url(../images/22x22/notifications.png); }
|
||||
.icon22-system_notification { background-image: url(../images/22x22/system_notification.png); }
|
||||
.icon22-authent { background-image: url(../images/22x22/authent.png); }
|
||||
.icon22-info { background-image: url(../images/22x22/info.png); }
|
||||
.icon22-comment { background-image: url(../images/22x22/comment.png); }
|
||||
.icon22-package { background-image: url(../images/22x22/package.png); }
|
||||
.icon22-settings { background-image: url(../images/22x22/settings.png); }
|
||||
.icon22-plugin { background-image: url(../images/22x22/plugin.png); }
|
||||
|
||||
img.gravatar {
|
||||
padding: 2px;
|
||||
border: solid 1px #d5d5d5;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
div.issue img.gravatar {
|
||||
float: right;
|
||||
margin: 0 0 0 1em;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.issue table img.gravatar {
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
padding: 2px;
|
||||
float: left;
|
||||
margin: 0 0.5em 0 0;
|
||||
}
|
||||
|
||||
#history img.gravatar {
|
||||
padding: 3px;
|
||||
margin: 0 1.5em 1em 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
td.username img.gravatar {
|
||||
float: left;
|
||||
margin: 0 1em 0 0;
|
||||
}
|
||||
|
||||
#activity dt img.gravatar {
|
||||
float: left;
|
||||
margin: 0 1em 1em 0;
|
||||
}
|
||||
|
||||
#activity dt,
|
||||
.journal {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.gravatar-margin {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
h2 img { vertical-align:middle; }
|
||||
|
||||
|
||||
/***** Media print specific styles *****/
|
||||
@media print {
|
||||
#top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
|
||||
#main { background: #fff; }
|
||||
#content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
|
||||
#wiki_add_attachment { display:none; }
|
||||
}
|
||||
|
||||
@import "ui-lightness/jquery-ui-1.7.2.custom.css";
|
||||
209
docs/application.js
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/* redMine - project management software
|
||||
Copyright (C) 2006-2008 Jean-Philippe Lang */
|
||||
|
||||
function checkAll (id, checked) {
|
||||
var els = Element.descendants(id);
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
if (els[i].disabled==false) {
|
||||
els[i].checked = checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleCheckboxesBySelector(selector) {
|
||||
boxes = $$(selector);
|
||||
var all_checked = true;
|
||||
for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
|
||||
for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
|
||||
}
|
||||
|
||||
function showAndScrollTo(id, focus) {
|
||||
Element.show(id);
|
||||
if (focus!=null) { Form.Element.focus(focus); }
|
||||
Element.scrollTo(id);
|
||||
}
|
||||
|
||||
function toggleRowGroup(el) {
|
||||
var tr = Element.up(el, 'tr');
|
||||
var n = Element.next(tr);
|
||||
tr.toggleClassName('open');
|
||||
while (n != undefined && !n.hasClassName('group')) {
|
||||
Element.toggle(n);
|
||||
n = Element.next(n);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFieldset(el) {
|
||||
var fieldset = Element.up(el, 'fieldset');
|
||||
fieldset.toggleClassName('collapsed');
|
||||
Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
|
||||
}
|
||||
|
||||
var fileFieldCount = 1;
|
||||
|
||||
function addFileField() {
|
||||
if (fileFieldCount >= 10) return false
|
||||
fileFieldCount++;
|
||||
var f = document.createElement("input");
|
||||
f.type = "file";
|
||||
f.name = "attachments[" + fileFieldCount + "][file]";
|
||||
f.size = 30;
|
||||
var d = document.createElement("input");
|
||||
d.type = "text";
|
||||
d.name = "attachments[" + fileFieldCount + "][description]";
|
||||
d.size = 60;
|
||||
|
||||
p = document.getElementById("attachments_fields");
|
||||
p.appendChild(document.createElement("br"));
|
||||
p.appendChild(f);
|
||||
p.appendChild(d);
|
||||
}
|
||||
|
||||
function showTab(name) {
|
||||
var f = $$('div#content .tab-content');
|
||||
for(var i=0; i<f.length; i++){
|
||||
Element.hide(f[i]);
|
||||
}
|
||||
var f = $$('div.tabs a');
|
||||
for(var i=0; i<f.length; i++){
|
||||
Element.removeClassName(f[i], "selected");
|
||||
}
|
||||
Element.show('tab-content-' + name);
|
||||
Element.addClassName('tab-' + name, "selected");
|
||||
return false;
|
||||
}
|
||||
|
||||
function moveTabRight(el) {
|
||||
var lis = Element.up(el, 'div.tabs').down('ul').childElements();
|
||||
var tabsWidth = 0;
|
||||
var i;
|
||||
for (i=0; i<lis.length; i++) {
|
||||
if (lis[i].visible()) {
|
||||
tabsWidth += lis[i].getWidth() + 6;
|
||||
}
|
||||
}
|
||||
if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
|
||||
return;
|
||||
}
|
||||
i=0;
|
||||
while (i<lis.length && !lis[i].visible()) {
|
||||
i++;
|
||||
}
|
||||
lis[i].hide();
|
||||
}
|
||||
|
||||
function moveTabLeft(el) {
|
||||
var lis = Element.up(el, 'div.tabs').down('ul').childElements();
|
||||
var i = 0;
|
||||
while (i<lis.length && !lis[i].visible()) {
|
||||
i++;
|
||||
}
|
||||
if (i>0) {
|
||||
lis[i-1].show();
|
||||
}
|
||||
}
|
||||
|
||||
function displayTabsButtons() {
|
||||
var lis;
|
||||
var tabsWidth = 0;
|
||||
var i;
|
||||
$$('div.tabs').each(function(el) {
|
||||
lis = el.down('ul').childElements();
|
||||
for (i=0; i<lis.length; i++) {
|
||||
if (lis[i].visible()) {
|
||||
tabsWidth += lis[i].getWidth() + 6;
|
||||
}
|
||||
}
|
||||
if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
|
||||
el.down('div.tabs-buttons').hide();
|
||||
} else {
|
||||
el.down('div.tabs-buttons').show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setPredecessorFieldsVisibility() {
|
||||
relationType = $('relation_relation_type');
|
||||
if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
|
||||
Element.show('predecessor_fields');
|
||||
} else {
|
||||
Element.hide('predecessor_fields');
|
||||
}
|
||||
}
|
||||
|
||||
function promptToRemote(text, param, url) {
|
||||
value = prompt(text + ':');
|
||||
if (value) {
|
||||
new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function collapseScmEntry(id) {
|
||||
var els = document.getElementsByClassName(id, 'browser');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
if (els[i].hasClassName('open')) {
|
||||
collapseScmEntry(els[i].id);
|
||||
}
|
||||
Element.hide(els[i]);
|
||||
}
|
||||
$(id).removeClassName('open');
|
||||
}
|
||||
|
||||
function expandScmEntry(id) {
|
||||
var els = document.getElementsByClassName(id, 'browser');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
Element.show(els[i]);
|
||||
if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
|
||||
expandScmEntry(els[i].id);
|
||||
}
|
||||
}
|
||||
$(id).addClassName('open');
|
||||
}
|
||||
|
||||
function scmEntryClick(id) {
|
||||
el = $(id);
|
||||
if (el.hasClassName('open')) {
|
||||
collapseScmEntry(id);
|
||||
el.addClassName('collapsed');
|
||||
return false;
|
||||
} else if (el.hasClassName('loaded')) {
|
||||
expandScmEntry(id);
|
||||
el.removeClassName('collapsed');
|
||||
return false;
|
||||
}
|
||||
if (el.hasClassName('loading')) {
|
||||
return false;
|
||||
}
|
||||
el.addClassName('loading');
|
||||
return true;
|
||||
}
|
||||
|
||||
function scmEntryLoaded(id) {
|
||||
Element.addClassName(id, 'open');
|
||||
Element.addClassName(id, 'loaded');
|
||||
Element.removeClassName(id, 'loading');
|
||||
}
|
||||
|
||||
function randomKey(size) {
|
||||
var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
|
||||
var key = '';
|
||||
for (i = 0; i < size; i++) {
|
||||
key += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/* shows and hides ajax indicator */
|
||||
Ajax.Responders.register({
|
||||
onCreate: function(){
|
||||
if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
|
||||
Element.show('ajax-indicator');
|
||||
}
|
||||
},
|
||||
onComplete: function(){
|
||||
if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
|
||||
Element.hide('ajax-indicator');
|
||||
}
|
||||
}
|
||||
});
|
||||
BIN
docs/attachment.png
Normal file
|
After Width: | Height: | Size: 995 B |
BIN
docs/balloons.png
Normal file
|
After Width: | Height: | Size: 715 B |
BIN
docs/clipline-small.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
963
docs/controls.js
vendored
Normal file
|
|
@ -0,0 +1,963 @@
|
|||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
||||
// (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
|
||||
// Contributors:
|
||||
// Richard Livsey
|
||||
// Rahul Bhargava
|
||||
// Rob Wills
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
// Autocompleter.Base handles all the autocompletion functionality
|
||||
// that's independent of the data source for autocompletion. This
|
||||
// includes drawing the autocompletion menu, observing keyboard
|
||||
// and mouse events, and similar.
|
||||
//
|
||||
// Specific autocompleters need to provide, at the very least,
|
||||
// a getUpdatedChoices function that will be invoked every time
|
||||
// the text inside the monitored textbox changes. This method
|
||||
// should get the text for which to provide autocompletion by
|
||||
// invoking this.getToken(), NOT by directly accessing
|
||||
// this.element.value. This is to allow incremental tokenized
|
||||
// autocompletion. Specific auto-completion logic (AJAX, etc)
|
||||
// belongs in getUpdatedChoices.
|
||||
//
|
||||
// Tokenized incremental autocompletion is enabled automatically
|
||||
// when an autocompleter is instantiated with the 'tokens' option
|
||||
// in the options parameter, e.g.:
|
||||
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
|
||||
// will incrementally autocomplete with a comma as the token.
|
||||
// Additionally, ',' in the above example can be replaced with
|
||||
// a token array, e.g. { tokens: [',', '\n'] } which
|
||||
// enables autocompletion on multiple tokens. This is most
|
||||
// useful when one of the tokens is \n (a newline), as it
|
||||
// allows smart autocompletion after linebreaks.
|
||||
|
||||
if(typeof Effect == 'undefined')
|
||||
throw("controls.js requires including script.aculo.us' effects.js library");
|
||||
|
||||
var Autocompleter = { };
|
||||
Autocompleter.Base = Class.create({
|
||||
baseInitialize: function(element, update, options) {
|
||||
element = $(element);
|
||||
this.element = element;
|
||||
this.update = $(update);
|
||||
this.hasFocus = false;
|
||||
this.changed = false;
|
||||
this.active = false;
|
||||
this.index = 0;
|
||||
this.entryCount = 0;
|
||||
this.oldElementValue = this.element.value;
|
||||
|
||||
if(this.setOptions)
|
||||
this.setOptions(options);
|
||||
else
|
||||
this.options = options || { };
|
||||
|
||||
this.options.paramName = this.options.paramName || this.element.name;
|
||||
this.options.tokens = this.options.tokens || [];
|
||||
this.options.frequency = this.options.frequency || 0.4;
|
||||
this.options.minChars = this.options.minChars || 1;
|
||||
this.options.onShow = this.options.onShow ||
|
||||
function(element, update){
|
||||
if(!update.style.position || update.style.position=='absolute') {
|
||||
update.style.position = 'absolute';
|
||||
Position.clone(element, update, {
|
||||
setHeight: false,
|
||||
offsetTop: element.offsetHeight
|
||||
});
|
||||
}
|
||||
Effect.Appear(update,{duration:0.15});
|
||||
};
|
||||
this.options.onHide = this.options.onHide ||
|
||||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
|
||||
|
||||
if(typeof(this.options.tokens) == 'string')
|
||||
this.options.tokens = new Array(this.options.tokens);
|
||||
// Force carriage returns as token delimiters anyway
|
||||
if (!this.options.tokens.include('\n'))
|
||||
this.options.tokens.push('\n');
|
||||
|
||||
this.observer = null;
|
||||
|
||||
this.element.setAttribute('autocomplete','off');
|
||||
|
||||
Element.hide(this.update);
|
||||
|
||||
Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
|
||||
Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
|
||||
if(!this.iefix &&
|
||||
(Prototype.Browser.IE) &&
|
||||
(Element.getStyle(this.update, 'position')=='absolute')) {
|
||||
new Insertion.After(this.update,
|
||||
'<iframe id="' + this.update.id + '_iefix" '+
|
||||
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
|
||||
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
|
||||
this.iefix = $(this.update.id+'_iefix');
|
||||
}
|
||||
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
|
||||
},
|
||||
|
||||
fixIEOverlapping: function() {
|
||||
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
|
||||
this.iefix.style.zIndex = 1;
|
||||
this.update.style.zIndex = 2;
|
||||
Element.show(this.iefix);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.stopIndicator();
|
||||
if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
|
||||
if(this.iefix) Element.hide(this.iefix);
|
||||
},
|
||||
|
||||
startIndicator: function() {
|
||||
if(this.options.indicator) Element.show(this.options.indicator);
|
||||
},
|
||||
|
||||
stopIndicator: function() {
|
||||
if(this.options.indicator) Element.hide(this.options.indicator);
|
||||
},
|
||||
|
||||
onKeyPress: function(event) {
|
||||
if(this.active)
|
||||
switch(event.keyCode) {
|
||||
case Event.KEY_TAB:
|
||||
case Event.KEY_RETURN:
|
||||
this.selectEntry();
|
||||
Event.stop(event);
|
||||
case Event.KEY_ESC:
|
||||
this.hide();
|
||||
this.active = false;
|
||||
Event.stop(event);
|
||||
return;
|
||||
case Event.KEY_LEFT:
|
||||
case Event.KEY_RIGHT:
|
||||
return;
|
||||
case Event.KEY_UP:
|
||||
this.markPrevious();
|
||||
this.render();
|
||||
Event.stop(event);
|
||||
return;
|
||||
case Event.KEY_DOWN:
|
||||
this.markNext();
|
||||
this.render();
|
||||
Event.stop(event);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
|
||||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
|
||||
|
||||
this.changed = true;
|
||||
this.hasFocus = true;
|
||||
|
||||
if(this.observer) clearTimeout(this.observer);
|
||||
this.observer =
|
||||
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this.changed = false;
|
||||
this.hasFocus = true;
|
||||
this.getUpdatedChoices();
|
||||
},
|
||||
|
||||
onHover: function(event) {
|
||||
var element = Event.findElement(event, 'LI');
|
||||
if(this.index != element.autocompleteIndex)
|
||||
{
|
||||
this.index = element.autocompleteIndex;
|
||||
this.render();
|
||||
}
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
onClick: function(event) {
|
||||
var element = Event.findElement(event, 'LI');
|
||||
this.index = element.autocompleteIndex;
|
||||
this.selectEntry();
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onBlur: function(event) {
|
||||
// needed to make click events working
|
||||
setTimeout(this.hide.bind(this), 250);
|
||||
this.hasFocus = false;
|
||||
this.active = false;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if(this.entryCount > 0) {
|
||||
for (var i = 0; i < this.entryCount; i++)
|
||||
this.index==i ?
|
||||
Element.addClassName(this.getEntry(i),"selected") :
|
||||
Element.removeClassName(this.getEntry(i),"selected");
|
||||
if(this.hasFocus) {
|
||||
this.show();
|
||||
this.active = true;
|
||||
}
|
||||
} else {
|
||||
this.active = false;
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
markPrevious: function() {
|
||||
if(this.index > 0) this.index--;
|
||||
else this.index = this.entryCount-1;
|
||||
this.getEntry(this.index).scrollIntoView(true);
|
||||
},
|
||||
|
||||
markNext: function() {
|
||||
if(this.index < this.entryCount-1) this.index++;
|
||||
else this.index = 0;
|
||||
this.getEntry(this.index).scrollIntoView(false);
|
||||
},
|
||||
|
||||
getEntry: function(index) {
|
||||
return this.update.firstChild.childNodes[index];
|
||||
},
|
||||
|
||||
getCurrentEntry: function() {
|
||||
return this.getEntry(this.index);
|
||||
},
|
||||
|
||||
selectEntry: function() {
|
||||
this.active = false;
|
||||
this.updateElement(this.getCurrentEntry());
|
||||
},
|
||||
|
||||
updateElement: function(selectedElement) {
|
||||
if (this.options.updateElement) {
|
||||
this.options.updateElement(selectedElement);
|
||||
return;
|
||||
}
|
||||
var value = '';
|
||||
if (this.options.select) {
|
||||
var nodes = $(selectedElement).select('.' + this.options.select) || [];
|
||||
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
|
||||
} else
|
||||
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
|
||||
|
||||
var bounds = this.getTokenBounds();
|
||||
if (bounds[0] != -1) {
|
||||
var newValue = this.element.value.substr(0, bounds[0]);
|
||||
var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
|
||||
if (whitespace)
|
||||
newValue += whitespace[0];
|
||||
this.element.value = newValue + value + this.element.value.substr(bounds[1]);
|
||||
} else {
|
||||
this.element.value = value;
|
||||
}
|
||||
this.oldElementValue = this.element.value;
|
||||
this.element.focus();
|
||||
|
||||
if (this.options.afterUpdateElement)
|
||||
this.options.afterUpdateElement(this.element, selectedElement);
|
||||
},
|
||||
|
||||
updateChoices: function(choices) {
|
||||
if(!this.changed && this.hasFocus) {
|
||||
this.update.innerHTML = choices;
|
||||
Element.cleanWhitespace(this.update);
|
||||
Element.cleanWhitespace(this.update.down());
|
||||
|
||||
if(this.update.firstChild && this.update.down().childNodes) {
|
||||
this.entryCount =
|
||||
this.update.down().childNodes.length;
|
||||
for (var i = 0; i < this.entryCount; i++) {
|
||||
var entry = this.getEntry(i);
|
||||
entry.autocompleteIndex = i;
|
||||
this.addObservers(entry);
|
||||
}
|
||||
} else {
|
||||
this.entryCount = 0;
|
||||
}
|
||||
|
||||
this.stopIndicator();
|
||||
this.index = 0;
|
||||
|
||||
if(this.entryCount==1 && this.options.autoSelect) {
|
||||
this.selectEntry();
|
||||
this.hide();
|
||||
} else {
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addObservers: function(element) {
|
||||
Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
|
||||
Event.observe(element, "click", this.onClick.bindAsEventListener(this));
|
||||
},
|
||||
|
||||
onObserverEvent: function() {
|
||||
this.changed = false;
|
||||
this.tokenBounds = null;
|
||||
if(this.getToken().length>=this.options.minChars) {
|
||||
this.getUpdatedChoices();
|
||||
} else {
|
||||
this.active = false;
|
||||
this.hide();
|
||||
}
|
||||
this.oldElementValue = this.element.value;
|
||||
},
|
||||
|
||||
getToken: function() {
|
||||
var bounds = this.getTokenBounds();
|
||||
return this.element.value.substring(bounds[0], bounds[1]).strip();
|
||||
},
|
||||
|
||||
getTokenBounds: function() {
|
||||
if (null != this.tokenBounds) return this.tokenBounds;
|
||||
var value = this.element.value;
|
||||
if (value.strip().empty()) return [-1, 0];
|
||||
var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
|
||||
var offset = (diff == this.oldElementValue.length ? 1 : 0);
|
||||
var prevTokenPos = -1, nextTokenPos = value.length;
|
||||
var tp;
|
||||
for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
|
||||
tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
|
||||
if (tp > prevTokenPos) prevTokenPos = tp;
|
||||
tp = value.indexOf(this.options.tokens[index], diff + offset);
|
||||
if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
|
||||
}
|
||||
return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
|
||||
}
|
||||
});
|
||||
|
||||
Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
|
||||
var boundary = Math.min(newS.length, oldS.length);
|
||||
for (var index = 0; index < boundary; ++index)
|
||||
if (newS[index] != oldS[index])
|
||||
return index;
|
||||
return boundary;
|
||||
};
|
||||
|
||||
Ajax.Autocompleter = Class.create(Autocompleter.Base, {
|
||||
initialize: function(element, update, url, options) {
|
||||
this.baseInitialize(element, update, options);
|
||||
this.options.asynchronous = true;
|
||||
this.options.onComplete = this.onComplete.bind(this);
|
||||
this.options.defaultParams = this.options.parameters || null;
|
||||
this.url = url;
|
||||
},
|
||||
|
||||
getUpdatedChoices: function() {
|
||||
this.startIndicator();
|
||||
|
||||
var entry = encodeURIComponent(this.options.paramName) + '=' +
|
||||
encodeURIComponent(this.getToken());
|
||||
|
||||
this.options.parameters = this.options.callback ?
|
||||
this.options.callback(this.element, entry) : entry;
|
||||
|
||||
if(this.options.defaultParams)
|
||||
this.options.parameters += '&' + this.options.defaultParams;
|
||||
|
||||
new Ajax.Request(this.url, this.options);
|
||||
},
|
||||
|
||||
onComplete: function(request) {
|
||||
this.updateChoices(request.responseText);
|
||||
}
|
||||
});
|
||||
|
||||
// The local array autocompleter. Used when you'd prefer to
|
||||
// inject an array of autocompletion options into the page, rather
|
||||
// than sending out Ajax queries, which can be quite slow sometimes.
|
||||
//
|
||||
// The constructor takes four parameters. The first two are, as usual,
|
||||
// the id of the monitored textbox, and id of the autocompletion menu.
|
||||
// The third is the array you want to autocomplete from, and the fourth
|
||||
// is the options block.
|
||||
//
|
||||
// Extra local autocompletion options:
|
||||
// - choices - How many autocompletion choices to offer
|
||||
//
|
||||
// - partialSearch - If false, the autocompleter will match entered
|
||||
// text only at the beginning of strings in the
|
||||
// autocomplete array. Defaults to true, which will
|
||||
// match text at the beginning of any *word* in the
|
||||
// strings in the autocomplete array. If you want to
|
||||
// search anywhere in the string, additionally set
|
||||
// the option fullSearch to true (default: off).
|
||||
//
|
||||
// - fullSsearch - Search anywhere in autocomplete array strings.
|
||||
//
|
||||
// - partialChars - How many characters to enter before triggering
|
||||
// a partial match (unlike minChars, which defines
|
||||
// how many characters are required to do any match
|
||||
// at all). Defaults to 2.
|
||||
//
|
||||
// - ignoreCase - Whether to ignore case when autocompleting.
|
||||
// Defaults to true.
|
||||
//
|
||||
// It's possible to pass in a custom function as the 'selector'
|
||||
// option, if you prefer to write your own autocompletion logic.
|
||||
// In that case, the other options above will not apply unless
|
||||
// you support them.
|
||||
|
||||
Autocompleter.Local = Class.create(Autocompleter.Base, {
|
||||
initialize: function(element, update, array, options) {
|
||||
this.baseInitialize(element, update, options);
|
||||
this.options.array = array;
|
||||
},
|
||||
|
||||
getUpdatedChoices: function() {
|
||||
this.updateChoices(this.options.selector(this));
|
||||
},
|
||||
|
||||
setOptions: function(options) {
|
||||
this.options = Object.extend({
|
||||
choices: 10,
|
||||
partialSearch: true,
|
||||
partialChars: 2,
|
||||
ignoreCase: true,
|
||||
fullSearch: false,
|
||||
selector: function(instance) {
|
||||
var ret = []; // Beginning matches
|
||||
var partial = []; // Inside matches
|
||||
var entry = instance.getToken();
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < instance.options.array.length &&
|
||||
ret.length < instance.options.choices ; i++) {
|
||||
|
||||
var elem = instance.options.array[i];
|
||||
var foundPos = instance.options.ignoreCase ?
|
||||
elem.toLowerCase().indexOf(entry.toLowerCase()) :
|
||||
elem.indexOf(entry);
|
||||
|
||||
while (foundPos != -1) {
|
||||
if (foundPos == 0 && elem.length != entry.length) {
|
||||
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
|
||||
elem.substr(entry.length) + "</li>");
|
||||
break;
|
||||
} else if (entry.length >= instance.options.partialChars &&
|
||||
instance.options.partialSearch && foundPos != -1) {
|
||||
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
|
||||
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
|
||||
elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
|
||||
foundPos + entry.length) + "</li>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foundPos = instance.options.ignoreCase ?
|
||||
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
|
||||
elem.indexOf(entry, foundPos + 1);
|
||||
|
||||
}
|
||||
}
|
||||
if (partial.length)
|
||||
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
|
||||
return "<ul>" + ret.join('') + "</ul>";
|
||||
}
|
||||
}, options || { });
|
||||
}
|
||||
});
|
||||
|
||||
// AJAX in-place editor and collection editor
|
||||
// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
|
||||
|
||||
// Use this if you notice weird scrolling problems on some browsers,
|
||||
// the DOM might be a bit confused when this gets called so do this
|
||||
// waits 1 ms (with setTimeout) until it does the activation
|
||||
Field.scrollFreeActivate = function(field) {
|
||||
setTimeout(function() {
|
||||
Field.activate(field);
|
||||
}, 1);
|
||||
};
|
||||
|
||||
Ajax.InPlaceEditor = Class.create({
|
||||
initialize: function(element, url, options) {
|
||||
this.url = url;
|
||||
this.element = element = $(element);
|
||||
this.prepareOptions();
|
||||
this._controls = { };
|
||||
arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
|
||||
Object.extend(this.options, options || { });
|
||||
if (!this.options.formId && this.element.id) {
|
||||
this.options.formId = this.element.id + '-inplaceeditor';
|
||||
if ($(this.options.formId))
|
||||
this.options.formId = '';
|
||||
}
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl = $(this.options.externalControl);
|
||||
if (!this.options.externalControl)
|
||||
this.options.externalControlOnly = false;
|
||||
this._originalBackground = this.element.getStyle('background-color') || 'transparent';
|
||||
this.element.title = this.options.clickToEditText;
|
||||
this._boundCancelHandler = this.handleFormCancellation.bind(this);
|
||||
this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
|
||||
this._boundFailureHandler = this.handleAJAXFailure.bind(this);
|
||||
this._boundSubmitHandler = this.handleFormSubmission.bind(this);
|
||||
this._boundWrapperHandler = this.wrapUp.bind(this);
|
||||
this.registerListeners();
|
||||
},
|
||||
checkForEscapeOrReturn: function(e) {
|
||||
if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
|
||||
if (Event.KEY_ESC == e.keyCode)
|
||||
this.handleFormCancellation(e);
|
||||
else if (Event.KEY_RETURN == e.keyCode)
|
||||
this.handleFormSubmission(e);
|
||||
},
|
||||
createControl: function(mode, handler, extraClasses) {
|
||||
var control = this.options[mode + 'Control'];
|
||||
var text = this.options[mode + 'Text'];
|
||||
if ('button' == control) {
|
||||
var btn = document.createElement('input');
|
||||
btn.type = 'submit';
|
||||
btn.value = text;
|
||||
btn.className = 'editor_' + mode + '_button';
|
||||
if ('cancel' == mode)
|
||||
btn.onclick = this._boundCancelHandler;
|
||||
this._form.appendChild(btn);
|
||||
this._controls[mode] = btn;
|
||||
} else if ('link' == control) {
|
||||
var link = document.createElement('a');
|
||||
link.href = '#';
|
||||
link.appendChild(document.createTextNode(text));
|
||||
link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
|
||||
link.className = 'editor_' + mode + '_link';
|
||||
if (extraClasses)
|
||||
link.className += ' ' + extraClasses;
|
||||
this._form.appendChild(link);
|
||||
this._controls[mode] = link;
|
||||
}
|
||||
},
|
||||
createEditField: function() {
|
||||
var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
|
||||
var fld;
|
||||
if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
|
||||
fld = document.createElement('input');
|
||||
fld.type = 'text';
|
||||
var size = this.options.size || this.options.cols || 0;
|
||||
if (0 < size) fld.size = size;
|
||||
} else {
|
||||
fld = document.createElement('textarea');
|
||||
fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
|
||||
fld.cols = this.options.cols || 40;
|
||||
}
|
||||
fld.name = this.options.paramName;
|
||||
fld.value = text; // No HTML breaks conversion anymore
|
||||
fld.className = 'editor_field';
|
||||
if (this.options.submitOnBlur)
|
||||
fld.onblur = this._boundSubmitHandler;
|
||||
this._controls.editor = fld;
|
||||
if (this.options.loadTextURL)
|
||||
this.loadExternalText();
|
||||
this._form.appendChild(this._controls.editor);
|
||||
},
|
||||
createForm: function() {
|
||||
var ipe = this;
|
||||
function addText(mode, condition) {
|
||||
var text = ipe.options['text' + mode + 'Controls'];
|
||||
if (!text || condition === false) return;
|
||||
ipe._form.appendChild(document.createTextNode(text));
|
||||
};
|
||||
this._form = $(document.createElement('form'));
|
||||
this._form.id = this.options.formId;
|
||||
this._form.addClassName(this.options.formClassName);
|
||||
this._form.onsubmit = this._boundSubmitHandler;
|
||||
this.createEditField();
|
||||
if ('textarea' == this._controls.editor.tagName.toLowerCase())
|
||||
this._form.appendChild(document.createElement('br'));
|
||||
if (this.options.onFormCustomization)
|
||||
this.options.onFormCustomization(this, this._form);
|
||||
addText('Before', this.options.okControl || this.options.cancelControl);
|
||||
this.createControl('ok', this._boundSubmitHandler);
|
||||
addText('Between', this.options.okControl && this.options.cancelControl);
|
||||
this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
|
||||
addText('After', this.options.okControl || this.options.cancelControl);
|
||||
},
|
||||
destroy: function() {
|
||||
if (this._oldInnerHTML)
|
||||
this.element.innerHTML = this._oldInnerHTML;
|
||||
this.leaveEditMode();
|
||||
this.unregisterListeners();
|
||||
},
|
||||
enterEditMode: function(e) {
|
||||
if (this._saving || this._editing) return;
|
||||
this._editing = true;
|
||||
this.triggerCallback('onEnterEditMode');
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.hide();
|
||||
this.element.hide();
|
||||
this.createForm();
|
||||
this.element.parentNode.insertBefore(this._form, this.element);
|
||||
if (!this.options.loadTextURL)
|
||||
this.postProcessEditField();
|
||||
if (e) Event.stop(e);
|
||||
},
|
||||
enterHover: function(e) {
|
||||
if (this.options.hoverClassName)
|
||||
this.element.addClassName(this.options.hoverClassName);
|
||||
if (this._saving) return;
|
||||
this.triggerCallback('onEnterHover');
|
||||
},
|
||||
getText: function() {
|
||||
return this.element.innerHTML.unescapeHTML();
|
||||
},
|
||||
handleAJAXFailure: function(transport) {
|
||||
this.triggerCallback('onFailure', transport);
|
||||
if (this._oldInnerHTML) {
|
||||
this.element.innerHTML = this._oldInnerHTML;
|
||||
this._oldInnerHTML = null;
|
||||
}
|
||||
},
|
||||
handleFormCancellation: function(e) {
|
||||
this.wrapUp();
|
||||
if (e) Event.stop(e);
|
||||
},
|
||||
handleFormSubmission: function(e) {
|
||||
var form = this._form;
|
||||
var value = $F(this._controls.editor);
|
||||
this.prepareSubmission();
|
||||
var params = this.options.callback(form, value) || '';
|
||||
if (Object.isString(params))
|
||||
params = params.toQueryParams();
|
||||
params.editorId = this.element.id;
|
||||
if (this.options.htmlResponse) {
|
||||
var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: params,
|
||||
onComplete: this._boundWrapperHandler,
|
||||
onFailure: this._boundFailureHandler
|
||||
});
|
||||
new Ajax.Updater({ success: this.element }, this.url, options);
|
||||
} else {
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: params,
|
||||
onComplete: this._boundWrapperHandler,
|
||||
onFailure: this._boundFailureHandler
|
||||
});
|
||||
new Ajax.Request(this.url, options);
|
||||
}
|
||||
if (e) Event.stop(e);
|
||||
},
|
||||
leaveEditMode: function() {
|
||||
this.element.removeClassName(this.options.savingClassName);
|
||||
this.removeForm();
|
||||
this.leaveHover();
|
||||
this.element.style.backgroundColor = this._originalBackground;
|
||||
this.element.show();
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.show();
|
||||
this._saving = false;
|
||||
this._editing = false;
|
||||
this._oldInnerHTML = null;
|
||||
this.triggerCallback('onLeaveEditMode');
|
||||
},
|
||||
leaveHover: function(e) {
|
||||
if (this.options.hoverClassName)
|
||||
this.element.removeClassName(this.options.hoverClassName);
|
||||
if (this._saving) return;
|
||||
this.triggerCallback('onLeaveHover');
|
||||
},
|
||||
loadExternalText: function() {
|
||||
this._form.addClassName(this.options.loadingClassName);
|
||||
this._controls.editor.disabled = true;
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
||||
onComplete: Prototype.emptyFunction,
|
||||
onSuccess: function(transport) {
|
||||
this._form.removeClassName(this.options.loadingClassName);
|
||||
var text = transport.responseText;
|
||||
if (this.options.stripLoadedTextTags)
|
||||
text = text.stripTags();
|
||||
this._controls.editor.value = text;
|
||||
this._controls.editor.disabled = false;
|
||||
this.postProcessEditField();
|
||||
}.bind(this),
|
||||
onFailure: this._boundFailureHandler
|
||||
});
|
||||
new Ajax.Request(this.options.loadTextURL, options);
|
||||
},
|
||||
postProcessEditField: function() {
|
||||
var fpc = this.options.fieldPostCreation;
|
||||
if (fpc)
|
||||
$(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
|
||||
},
|
||||
prepareOptions: function() {
|
||||
this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
|
||||
Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
|
||||
[this._extraDefaultOptions].flatten().compact().each(function(defs) {
|
||||
Object.extend(this.options, defs);
|
||||
}.bind(this));
|
||||
},
|
||||
prepareSubmission: function() {
|
||||
this._saving = true;
|
||||
this.removeForm();
|
||||
this.leaveHover();
|
||||
this.showSaving();
|
||||
},
|
||||
registerListeners: function() {
|
||||
this._listeners = { };
|
||||
var listener;
|
||||
$H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
|
||||
listener = this[pair.value].bind(this);
|
||||
this._listeners[pair.key] = listener;
|
||||
if (!this.options.externalControlOnly)
|
||||
this.element.observe(pair.key, listener);
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.observe(pair.key, listener);
|
||||
}.bind(this));
|
||||
},
|
||||
removeForm: function() {
|
||||
if (!this._form) return;
|
||||
this._form.remove();
|
||||
this._form = null;
|
||||
this._controls = { };
|
||||
},
|
||||
showSaving: function() {
|
||||
this._oldInnerHTML = this.element.innerHTML;
|
||||
this.element.innerHTML = this.options.savingText;
|
||||
this.element.addClassName(this.options.savingClassName);
|
||||
this.element.style.backgroundColor = this._originalBackground;
|
||||
this.element.show();
|
||||
},
|
||||
triggerCallback: function(cbName, arg) {
|
||||
if ('function' == typeof this.options[cbName]) {
|
||||
this.options[cbName](this, arg);
|
||||
}
|
||||
},
|
||||
unregisterListeners: function() {
|
||||
$H(this._listeners).each(function(pair) {
|
||||
if (!this.options.externalControlOnly)
|
||||
this.element.stopObserving(pair.key, pair.value);
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.stopObserving(pair.key, pair.value);
|
||||
}.bind(this));
|
||||
},
|
||||
wrapUp: function(transport) {
|
||||
this.leaveEditMode();
|
||||
// Can't use triggerCallback due to backward compatibility: requires
|
||||
// binding + direct element
|
||||
this._boundComplete(transport, this.element);
|
||||
}
|
||||
});
|
||||
|
||||
Object.extend(Ajax.InPlaceEditor.prototype, {
|
||||
dispose: Ajax.InPlaceEditor.prototype.destroy
|
||||
});
|
||||
|
||||
Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
|
||||
initialize: function($super, element, url, options) {
|
||||
this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
|
||||
$super(element, url, options);
|
||||
},
|
||||
|
||||
createEditField: function() {
|
||||
var list = document.createElement('select');
|
||||
list.name = this.options.paramName;
|
||||
list.size = 1;
|
||||
this._controls.editor = list;
|
||||
this._collection = this.options.collection || [];
|
||||
if (this.options.loadCollectionURL)
|
||||
this.loadCollection();
|
||||
else
|
||||
this.checkForExternalText();
|
||||
this._form.appendChild(this._controls.editor);
|
||||
},
|
||||
|
||||
loadCollection: function() {
|
||||
this._form.addClassName(this.options.loadingClassName);
|
||||
this.showLoadingText(this.options.loadingCollectionText);
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
||||
onComplete: Prototype.emptyFunction,
|
||||
onSuccess: function(transport) {
|
||||
var js = transport.responseText.strip();
|
||||
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
|
||||
throw('Server returned an invalid collection representation.');
|
||||
this._collection = eval(js);
|
||||
this.checkForExternalText();
|
||||
}.bind(this),
|
||||
onFailure: this.onFailure
|
||||
});
|
||||
new Ajax.Request(this.options.loadCollectionURL, options);
|
||||
},
|
||||
|
||||
showLoadingText: function(text) {
|
||||
this._controls.editor.disabled = true;
|
||||
var tempOption = this._controls.editor.firstChild;
|
||||
if (!tempOption) {
|
||||
tempOption = document.createElement('option');
|
||||
tempOption.value = '';
|
||||
this._controls.editor.appendChild(tempOption);
|
||||
tempOption.selected = true;
|
||||
}
|
||||
tempOption.update((text || '').stripScripts().stripTags());
|
||||
},
|
||||
|
||||
checkForExternalText: function() {
|
||||
this._text = this.getText();
|
||||
if (this.options.loadTextURL)
|
||||
this.loadExternalText();
|
||||
else
|
||||
this.buildOptionList();
|
||||
},
|
||||
|
||||
loadExternalText: function() {
|
||||
this.showLoadingText(this.options.loadingText);
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
||||
onComplete: Prototype.emptyFunction,
|
||||
onSuccess: function(transport) {
|
||||
this._text = transport.responseText.strip();
|
||||
this.buildOptionList();
|
||||
}.bind(this),
|
||||
onFailure: this.onFailure
|
||||
});
|
||||
new Ajax.Request(this.options.loadTextURL, options);
|
||||
},
|
||||
|
||||
buildOptionList: function() {
|
||||
this._form.removeClassName(this.options.loadingClassName);
|
||||
this._collection = this._collection.map(function(entry) {
|
||||
return 2 === entry.length ? entry : [entry, entry].flatten();
|
||||
});
|
||||
var marker = ('value' in this.options) ? this.options.value : this._text;
|
||||
var textFound = this._collection.any(function(entry) {
|
||||
return entry[0] == marker;
|
||||
}.bind(this));
|
||||
this._controls.editor.update('');
|
||||
var option;
|
||||
this._collection.each(function(entry, index) {
|
||||
option = document.createElement('option');
|
||||
option.value = entry[0];
|
||||
option.selected = textFound ? entry[0] == marker : 0 == index;
|
||||
option.appendChild(document.createTextNode(entry[1]));
|
||||
this._controls.editor.appendChild(option);
|
||||
}.bind(this));
|
||||
this._controls.editor.disabled = false;
|
||||
Field.scrollFreeActivate(this._controls.editor);
|
||||
}
|
||||
});
|
||||
|
||||
//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
|
||||
//**** This only exists for a while, in order to let ****
|
||||
//**** users adapt to the new API. Read up on the new ****
|
||||
//**** API and convert your code to it ASAP! ****
|
||||
|
||||
Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
|
||||
if (!options) return;
|
||||
function fallback(name, expr) {
|
||||
if (name in options || expr === undefined) return;
|
||||
options[name] = expr;
|
||||
};
|
||||
fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
|
||||
options.cancelLink == options.cancelButton == false ? false : undefined)));
|
||||
fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
|
||||
options.okLink == options.okButton == false ? false : undefined)));
|
||||
fallback('highlightColor', options.highlightcolor);
|
||||
fallback('highlightEndColor', options.highlightendcolor);
|
||||
};
|
||||
|
||||
Object.extend(Ajax.InPlaceEditor, {
|
||||
DefaultOptions: {
|
||||
ajaxOptions: { },
|
||||
autoRows: 3, // Use when multi-line w/ rows == 1
|
||||
cancelControl: 'link', // 'link'|'button'|false
|
||||
cancelText: 'cancel',
|
||||
clickToEditText: 'Click to edit',
|
||||
externalControl: null, // id|elt
|
||||
externalControlOnly: false,
|
||||
fieldPostCreation: 'activate', // 'activate'|'focus'|false
|
||||
formClassName: 'inplaceeditor-form',
|
||||
formId: null, // id|elt
|
||||
highlightColor: '#ffff99',
|
||||
highlightEndColor: '#ffffff',
|
||||
hoverClassName: '',
|
||||
htmlResponse: true,
|
||||
loadingClassName: 'inplaceeditor-loading',
|
||||
loadingText: 'Loading...',
|
||||
okControl: 'button', // 'link'|'button'|false
|
||||
okText: 'ok',
|
||||
paramName: 'value',
|
||||
rows: 1, // If 1 and multi-line, uses autoRows
|
||||
savingClassName: 'inplaceeditor-saving',
|
||||
savingText: 'Saving...',
|
||||
size: 0,
|
||||
stripLoadedTextTags: false,
|
||||
submitOnBlur: false,
|
||||
textAfterControls: '',
|
||||
textBeforeControls: '',
|
||||
textBetweenControls: ''
|
||||
},
|
||||
DefaultCallbacks: {
|
||||
callback: function(form) {
|
||||
return Form.serialize(form);
|
||||
},
|
||||
onComplete: function(transport, element) {
|
||||
// For backward compatibility, this one is bound to the IPE, and passes
|
||||
// the element directly. It was too often customized, so we don't break it.
|
||||
new Effect.Highlight(element, {
|
||||
startcolor: this.options.highlightColor, keepBackgroundImage: true });
|
||||
},
|
||||
onEnterEditMode: null,
|
||||
onEnterHover: function(ipe) {
|
||||
ipe.element.style.backgroundColor = ipe.options.highlightColor;
|
||||
if (ipe._effect)
|
||||
ipe._effect.cancel();
|
||||
},
|
||||
onFailure: function(transport, ipe) {
|
||||
alert('Error communication with the server: ' + transport.responseText.stripTags());
|
||||
},
|
||||
onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
|
||||
onLeaveEditMode: null,
|
||||
onLeaveHover: function(ipe) {
|
||||
ipe._effect = new Effect.Highlight(ipe.element, {
|
||||
startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
|
||||
restorecolor: ipe._originalBackground, keepBackgroundImage: true
|
||||
});
|
||||
}
|
||||
},
|
||||
Listeners: {
|
||||
click: 'enterEditMode',
|
||||
keydown: 'checkForEscapeOrReturn',
|
||||
mouseover: 'enterHover',
|
||||
mouseout: 'leaveHover'
|
||||
}
|
||||
});
|
||||
|
||||
Ajax.InPlaceCollectionEditor.DefaultOptions = {
|
||||
loadingCollectionText: 'Loading options...'
|
||||
};
|
||||
|
||||
// Delayed observer, like Form.Element.Observer,
|
||||
// but waits for delay after last key input
|
||||
// Ideal for live-search fields
|
||||
|
||||
Form.Element.DelayedObserver = Class.create({
|
||||
initialize: function(element, delay, callback) {
|
||||
this.delay = delay || 0.5;
|
||||
this.element = $(element);
|
||||
this.callback = callback;
|
||||
this.timer = null;
|
||||
this.lastValue = $F(this.element);
|
||||
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
|
||||
},
|
||||
delayedListener: function(event) {
|
||||
if(this.lastValue == $F(this.element)) return;
|
||||
if(this.timer) clearTimeout(this.timer);
|
||||
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
|
||||
this.lastValue = $F(this.element);
|
||||
},
|
||||
onTimerEvent: function() {
|
||||
this.timer = null;
|
||||
this.callback(this.element, $F(this.element));
|
||||
}
|
||||
});
|
||||
BIN
docs/document-horizontal-text.png
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
docs/document-text-image.png
Normal file
|
After Width: | Height: | Size: 647 B |
BIN
docs/document-zipper.png
Normal file
|
After Width: | Height: | Size: 646 B |
BIN
docs/documents-text.png
Normal file
|
After Width: | Height: | Size: 675 B |
BIN
docs/dotproduct-small.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
973
docs/dragdrop.js
vendored
Normal file
|
|
@ -0,0 +1,973 @@
|
|||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
if(Object.isUndefined(Effect))
|
||||
throw("dragdrop.js requires including script.aculo.us' effects.js library");
|
||||
|
||||
var Droppables = {
|
||||
drops: [],
|
||||
|
||||
remove: function(element) {
|
||||
this.drops = this.drops.reject(function(d) { return d.element==$(element) });
|
||||
},
|
||||
|
||||
add: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
greedy: true,
|
||||
hoverclass: null,
|
||||
tree: false
|
||||
}, arguments[1] || { });
|
||||
|
||||
// cache containers
|
||||
if(options.containment) {
|
||||
options._containers = [];
|
||||
var containment = options.containment;
|
||||
if(Object.isArray(containment)) {
|
||||
containment.each( function(c) { options._containers.push($(c)) });
|
||||
} else {
|
||||
options._containers.push($(containment));
|
||||
}
|
||||
}
|
||||
|
||||
if(options.accept) options.accept = [options.accept].flatten();
|
||||
|
||||
Element.makePositioned(element); // fix IE
|
||||
options.element = element;
|
||||
|
||||
this.drops.push(options);
|
||||
},
|
||||
|
||||
findDeepestChild: function(drops) {
|
||||
deepest = drops[0];
|
||||
|
||||
for (i = 1; i < drops.length; ++i)
|
||||
if (Element.isParent(drops[i].element, deepest.element))
|
||||
deepest = drops[i];
|
||||
|
||||
return deepest;
|
||||
},
|
||||
|
||||
isContained: function(element, drop) {
|
||||
var containmentNode;
|
||||
if(drop.tree) {
|
||||
containmentNode = element.treeNode;
|
||||
} else {
|
||||
containmentNode = element.parentNode;
|
||||
}
|
||||
return drop._containers.detect(function(c) { return containmentNode == c });
|
||||
},
|
||||
|
||||
isAffected: function(point, element, drop) {
|
||||
return (
|
||||
(drop.element!=element) &&
|
||||
((!drop._containers) ||
|
||||
this.isContained(element, drop)) &&
|
||||
((!drop.accept) ||
|
||||
(Element.classNames(element).detect(
|
||||
function(v) { return drop.accept.include(v) } ) )) &&
|
||||
Position.within(drop.element, point[0], point[1]) );
|
||||
},
|
||||
|
||||
deactivate: function(drop) {
|
||||
if(drop.hoverclass)
|
||||
Element.removeClassName(drop.element, drop.hoverclass);
|
||||
this.last_active = null;
|
||||
},
|
||||
|
||||
activate: function(drop) {
|
||||
if(drop.hoverclass)
|
||||
Element.addClassName(drop.element, drop.hoverclass);
|
||||
this.last_active = drop;
|
||||
},
|
||||
|
||||
show: function(point, element) {
|
||||
if(!this.drops.length) return;
|
||||
var drop, affected = [];
|
||||
|
||||
this.drops.each( function(drop) {
|
||||
if(Droppables.isAffected(point, element, drop))
|
||||
affected.push(drop);
|
||||
});
|
||||
|
||||
if(affected.length>0)
|
||||
drop = Droppables.findDeepestChild(affected);
|
||||
|
||||
if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
|
||||
if (drop) {
|
||||
Position.within(drop.element, point[0], point[1]);
|
||||
if(drop.onHover)
|
||||
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
|
||||
|
||||
if (drop != this.last_active) Droppables.activate(drop);
|
||||
}
|
||||
},
|
||||
|
||||
fire: function(event, element) {
|
||||
if(!this.last_active) return;
|
||||
Position.prepare();
|
||||
|
||||
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
|
||||
if (this.last_active.onDrop) {
|
||||
this.last_active.onDrop(element, this.last_active.element, event);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if(this.last_active)
|
||||
this.deactivate(this.last_active);
|
||||
}
|
||||
};
|
||||
|
||||
var Draggables = {
|
||||
drags: [],
|
||||
observers: [],
|
||||
|
||||
register: function(draggable) {
|
||||
if(this.drags.length == 0) {
|
||||
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
|
||||
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
|
||||
this.eventKeypress = this.keyPress.bindAsEventListener(this);
|
||||
|
||||
Event.observe(document, "mouseup", this.eventMouseUp);
|
||||
Event.observe(document, "mousemove", this.eventMouseMove);
|
||||
Event.observe(document, "keypress", this.eventKeypress);
|
||||
}
|
||||
this.drags.push(draggable);
|
||||
},
|
||||
|
||||
unregister: function(draggable) {
|
||||
this.drags = this.drags.reject(function(d) { return d==draggable });
|
||||
if(this.drags.length == 0) {
|
||||
Event.stopObserving(document, "mouseup", this.eventMouseUp);
|
||||
Event.stopObserving(document, "mousemove", this.eventMouseMove);
|
||||
Event.stopObserving(document, "keypress", this.eventKeypress);
|
||||
}
|
||||
},
|
||||
|
||||
activate: function(draggable) {
|
||||
if(draggable.options.delay) {
|
||||
this._timeout = setTimeout(function() {
|
||||
Draggables._timeout = null;
|
||||
window.focus();
|
||||
Draggables.activeDraggable = draggable;
|
||||
}.bind(this), draggable.options.delay);
|
||||
} else {
|
||||
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
|
||||
this.activeDraggable = draggable;
|
||||
}
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
this.activeDraggable = null;
|
||||
},
|
||||
|
||||
updateDrag: function(event) {
|
||||
if(!this.activeDraggable) return;
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
// Mozilla-based browsers fire successive mousemove events with
|
||||
// the same coordinates, prevent needless redrawing (moz bug?)
|
||||
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
|
||||
this._lastPointer = pointer;
|
||||
|
||||
this.activeDraggable.updateDrag(event, pointer);
|
||||
},
|
||||
|
||||
endDrag: function(event) {
|
||||
if(this._timeout) {
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
}
|
||||
if(!this.activeDraggable) return;
|
||||
this._lastPointer = null;
|
||||
this.activeDraggable.endDrag(event);
|
||||
this.activeDraggable = null;
|
||||
},
|
||||
|
||||
keyPress: function(event) {
|
||||
if(this.activeDraggable)
|
||||
this.activeDraggable.keyPress(event);
|
||||
},
|
||||
|
||||
addObserver: function(observer) {
|
||||
this.observers.push(observer);
|
||||
this._cacheObserverCallbacks();
|
||||
},
|
||||
|
||||
removeObserver: function(element) { // element instead of observer fixes mem leaks
|
||||
this.observers = this.observers.reject( function(o) { return o.element==element });
|
||||
this._cacheObserverCallbacks();
|
||||
},
|
||||
|
||||
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
|
||||
if(this[eventName+'Count'] > 0)
|
||||
this.observers.each( function(o) {
|
||||
if(o[eventName]) o[eventName](eventName, draggable, event);
|
||||
});
|
||||
if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
|
||||
},
|
||||
|
||||
_cacheObserverCallbacks: function() {
|
||||
['onStart','onEnd','onDrag'].each( function(eventName) {
|
||||
Draggables[eventName+'Count'] = Draggables.observers.select(
|
||||
function(o) { return o[eventName]; }
|
||||
).length;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var Draggable = Class.create({
|
||||
initialize: function(element) {
|
||||
var defaults = {
|
||||
handle: false,
|
||||
reverteffect: function(element, top_offset, left_offset) {
|
||||
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
|
||||
new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
|
||||
queue: {scope:'_draggable', position:'end'}
|
||||
});
|
||||
},
|
||||
endeffect: function(element) {
|
||||
var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
|
||||
new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
|
||||
queue: {scope:'_draggable', position:'end'},
|
||||
afterFinish: function(){
|
||||
Draggable._dragging[element] = false
|
||||
}
|
||||
});
|
||||
},
|
||||
zindex: 1000,
|
||||
revert: false,
|
||||
quiet: false,
|
||||
scroll: false,
|
||||
scrollSensitivity: 20,
|
||||
scrollSpeed: 15,
|
||||
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
|
||||
delay: 0
|
||||
};
|
||||
|
||||
if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
|
||||
Object.extend(defaults, {
|
||||
starteffect: function(element) {
|
||||
element._opacity = Element.getOpacity(element);
|
||||
Draggable._dragging[element] = true;
|
||||
new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
|
||||
}
|
||||
});
|
||||
|
||||
var options = Object.extend(defaults, arguments[1] || { });
|
||||
|
||||
this.element = $(element);
|
||||
|
||||
if(options.handle && Object.isString(options.handle))
|
||||
this.handle = this.element.down('.'+options.handle, 0);
|
||||
|
||||
if(!this.handle) this.handle = $(options.handle);
|
||||
if(!this.handle) this.handle = this.element;
|
||||
|
||||
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
|
||||
options.scroll = $(options.scroll);
|
||||
this._isScrollChild = Element.childOf(this.element, options.scroll);
|
||||
}
|
||||
|
||||
Element.makePositioned(this.element); // fix IE
|
||||
|
||||
this.options = options;
|
||||
this.dragging = false;
|
||||
|
||||
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
|
||||
Event.observe(this.handle, "mousedown", this.eventMouseDown);
|
||||
|
||||
Draggables.register(this);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
|
||||
Draggables.unregister(this);
|
||||
},
|
||||
|
||||
currentDelta: function() {
|
||||
return([
|
||||
parseInt(Element.getStyle(this.element,'left') || '0'),
|
||||
parseInt(Element.getStyle(this.element,'top') || '0')]);
|
||||
},
|
||||
|
||||
initDrag: function(event) {
|
||||
if(!Object.isUndefined(Draggable._dragging[this.element]) &&
|
||||
Draggable._dragging[this.element]) return;
|
||||
if(Event.isLeftClick(event)) {
|
||||
// abort on form elements, fixes a Firefox issue
|
||||
var src = Event.element(event);
|
||||
if((tag_name = src.tagName.toUpperCase()) && (
|
||||
tag_name=='INPUT' ||
|
||||
tag_name=='SELECT' ||
|
||||
tag_name=='OPTION' ||
|
||||
tag_name=='BUTTON' ||
|
||||
tag_name=='TEXTAREA')) return;
|
||||
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
var pos = Position.cumulativeOffset(this.element);
|
||||
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
|
||||
|
||||
Draggables.activate(this);
|
||||
Event.stop(event);
|
||||
}
|
||||
},
|
||||
|
||||
startDrag: function(event) {
|
||||
this.dragging = true;
|
||||
if(!this.delta)
|
||||
this.delta = this.currentDelta();
|
||||
|
||||
if(this.options.zindex) {
|
||||
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
|
||||
this.element.style.zIndex = this.options.zindex;
|
||||
}
|
||||
|
||||
if(this.options.ghosting) {
|
||||
this._clone = this.element.cloneNode(true);
|
||||
this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
|
||||
if (!this._originallyAbsolute)
|
||||
Position.absolutize(this.element);
|
||||
this.element.parentNode.insertBefore(this._clone, this.element);
|
||||
}
|
||||
|
||||
if(this.options.scroll) {
|
||||
if (this.options.scroll == window) {
|
||||
var where = this._getWindowScroll(this.options.scroll);
|
||||
this.originalScrollLeft = where.left;
|
||||
this.originalScrollTop = where.top;
|
||||
} else {
|
||||
this.originalScrollLeft = this.options.scroll.scrollLeft;
|
||||
this.originalScrollTop = this.options.scroll.scrollTop;
|
||||
}
|
||||
}
|
||||
|
||||
Draggables.notify('onStart', this, event);
|
||||
|
||||
if(this.options.starteffect) this.options.starteffect(this.element);
|
||||
},
|
||||
|
||||
updateDrag: function(event, pointer) {
|
||||
if(!this.dragging) this.startDrag(event);
|
||||
|
||||
if(!this.options.quiet){
|
||||
Position.prepare();
|
||||
Droppables.show(pointer, this.element);
|
||||
}
|
||||
|
||||
Draggables.notify('onDrag', this, event);
|
||||
|
||||
this.draw(pointer);
|
||||
if(this.options.change) this.options.change(this);
|
||||
|
||||
if(this.options.scroll) {
|
||||
this.stopScrolling();
|
||||
|
||||
var p;
|
||||
if (this.options.scroll == window) {
|
||||
with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
|
||||
} else {
|
||||
p = Position.page(this.options.scroll);
|
||||
p[0] += this.options.scroll.scrollLeft + Position.deltaX;
|
||||
p[1] += this.options.scroll.scrollTop + Position.deltaY;
|
||||
p.push(p[0]+this.options.scroll.offsetWidth);
|
||||
p.push(p[1]+this.options.scroll.offsetHeight);
|
||||
}
|
||||
var speed = [0,0];
|
||||
if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
|
||||
if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
|
||||
if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
|
||||
if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
|
||||
this.startScrolling(speed);
|
||||
}
|
||||
|
||||
// fix AppleWebKit rendering
|
||||
if(Prototype.Browser.WebKit) window.scrollBy(0,0);
|
||||
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
finishDrag: function(event, success) {
|
||||
this.dragging = false;
|
||||
|
||||
if(this.options.quiet){
|
||||
Position.prepare();
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
Droppables.show(pointer, this.element);
|
||||
}
|
||||
|
||||
if(this.options.ghosting) {
|
||||
if (!this._originallyAbsolute)
|
||||
Position.relativize(this.element);
|
||||
delete this._originallyAbsolute;
|
||||
Element.remove(this._clone);
|
||||
this._clone = null;
|
||||
}
|
||||
|
||||
var dropped = false;
|
||||
if(success) {
|
||||
dropped = Droppables.fire(event, this.element);
|
||||
if (!dropped) dropped = false;
|
||||
}
|
||||
if(dropped && this.options.onDropped) this.options.onDropped(this.element);
|
||||
Draggables.notify('onEnd', this, event);
|
||||
|
||||
var revert = this.options.revert;
|
||||
if(revert && Object.isFunction(revert)) revert = revert(this.element);
|
||||
|
||||
var d = this.currentDelta();
|
||||
if(revert && this.options.reverteffect) {
|
||||
if (dropped == 0 || revert != 'failure')
|
||||
this.options.reverteffect(this.element,
|
||||
d[1]-this.delta[1], d[0]-this.delta[0]);
|
||||
} else {
|
||||
this.delta = d;
|
||||
}
|
||||
|
||||
if(this.options.zindex)
|
||||
this.element.style.zIndex = this.originalZ;
|
||||
|
||||
if(this.options.endeffect)
|
||||
this.options.endeffect(this.element);
|
||||
|
||||
Draggables.deactivate(this);
|
||||
Droppables.reset();
|
||||
},
|
||||
|
||||
keyPress: function(event) {
|
||||
if(event.keyCode!=Event.KEY_ESC) return;
|
||||
this.finishDrag(event, false);
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
endDrag: function(event) {
|
||||
if(!this.dragging) return;
|
||||
this.stopScrolling();
|
||||
this.finishDrag(event, true);
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
draw: function(point) {
|
||||
var pos = Position.cumulativeOffset(this.element);
|
||||
if(this.options.ghosting) {
|
||||
var r = Position.realOffset(this.element);
|
||||
pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
|
||||
}
|
||||
|
||||
var d = this.currentDelta();
|
||||
pos[0] -= d[0]; pos[1] -= d[1];
|
||||
|
||||
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
|
||||
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
|
||||
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
|
||||
}
|
||||
|
||||
var p = [0,1].map(function(i){
|
||||
return (point[i]-pos[i]-this.offset[i])
|
||||
}.bind(this));
|
||||
|
||||
if(this.options.snap) {
|
||||
if(Object.isFunction(this.options.snap)) {
|
||||
p = this.options.snap(p[0],p[1],this);
|
||||
} else {
|
||||
if(Object.isArray(this.options.snap)) {
|
||||
p = p.map( function(v, i) {
|
||||
return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
|
||||
} else {
|
||||
p = p.map( function(v) {
|
||||
return (v/this.options.snap).round()*this.options.snap }.bind(this));
|
||||
}
|
||||
}}
|
||||
|
||||
var style = this.element.style;
|
||||
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
|
||||
style.left = p[0] + "px";
|
||||
if((!this.options.constraint) || (this.options.constraint=='vertical'))
|
||||
style.top = p[1] + "px";
|
||||
|
||||
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
|
||||
},
|
||||
|
||||
stopScrolling: function() {
|
||||
if(this.scrollInterval) {
|
||||
clearInterval(this.scrollInterval);
|
||||
this.scrollInterval = null;
|
||||
Draggables._lastScrollPointer = null;
|
||||
}
|
||||
},
|
||||
|
||||
startScrolling: function(speed) {
|
||||
if(!(speed[0] || speed[1])) return;
|
||||
this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
|
||||
this.lastScrolled = new Date();
|
||||
this.scrollInterval = setInterval(this.scroll.bind(this), 10);
|
||||
},
|
||||
|
||||
scroll: function() {
|
||||
var current = new Date();
|
||||
var delta = current - this.lastScrolled;
|
||||
this.lastScrolled = current;
|
||||
if(this.options.scroll == window) {
|
||||
with (this._getWindowScroll(this.options.scroll)) {
|
||||
if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
|
||||
var d = delta / 1000;
|
||||
this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
|
||||
this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
|
||||
}
|
||||
|
||||
Position.prepare();
|
||||
Droppables.show(Draggables._lastPointer, this.element);
|
||||
Draggables.notify('onDrag', this);
|
||||
if (this._isScrollChild) {
|
||||
Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
|
||||
Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
|
||||
Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
|
||||
if (Draggables._lastScrollPointer[0] < 0)
|
||||
Draggables._lastScrollPointer[0] = 0;
|
||||
if (Draggables._lastScrollPointer[1] < 0)
|
||||
Draggables._lastScrollPointer[1] = 0;
|
||||
this.draw(Draggables._lastScrollPointer);
|
||||
}
|
||||
|
||||
if(this.options.change) this.options.change(this);
|
||||
},
|
||||
|
||||
_getWindowScroll: function(w) {
|
||||
var T, L, W, H;
|
||||
with (w.document) {
|
||||
if (w.document.documentElement && documentElement.scrollTop) {
|
||||
T = documentElement.scrollTop;
|
||||
L = documentElement.scrollLeft;
|
||||
} else if (w.document.body) {
|
||||
T = body.scrollTop;
|
||||
L = body.scrollLeft;
|
||||
}
|
||||
if (w.innerWidth) {
|
||||
W = w.innerWidth;
|
||||
H = w.innerHeight;
|
||||
} else if (w.document.documentElement && documentElement.clientWidth) {
|
||||
W = documentElement.clientWidth;
|
||||
H = documentElement.clientHeight;
|
||||
} else {
|
||||
W = body.offsetWidth;
|
||||
H = body.offsetHeight;
|
||||
}
|
||||
}
|
||||
return { top: T, left: L, width: W, height: H };
|
||||
}
|
||||
});
|
||||
|
||||
Draggable._dragging = { };
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var SortableObserver = Class.create({
|
||||
initialize: function(element, observer) {
|
||||
this.element = $(element);
|
||||
this.observer = observer;
|
||||
this.lastValue = Sortable.serialize(this.element);
|
||||
},
|
||||
|
||||
onStart: function() {
|
||||
this.lastValue = Sortable.serialize(this.element);
|
||||
},
|
||||
|
||||
onEnd: function() {
|
||||
Sortable.unmark();
|
||||
if(this.lastValue != Sortable.serialize(this.element))
|
||||
this.observer(this.element)
|
||||
}
|
||||
});
|
||||
|
||||
var Sortable = {
|
||||
SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
|
||||
|
||||
sortables: { },
|
||||
|
||||
_findRootElement: function(element) {
|
||||
while (element.tagName.toUpperCase() != "BODY") {
|
||||
if(element.id && Sortable.sortables[element.id]) return element;
|
||||
element = element.parentNode;
|
||||
}
|
||||
},
|
||||
|
||||
options: function(element) {
|
||||
element = Sortable._findRootElement($(element));
|
||||
if(!element) return;
|
||||
return Sortable.sortables[element.id];
|
||||
},
|
||||
|
||||
destroy: function(element){
|
||||
element = $(element);
|
||||
var s = Sortable.sortables[element.id];
|
||||
|
||||
if(s) {
|
||||
Draggables.removeObserver(s.element);
|
||||
s.droppables.each(function(d){ Droppables.remove(d) });
|
||||
s.draggables.invoke('destroy');
|
||||
|
||||
delete Sortable.sortables[s.element.id];
|
||||
}
|
||||
},
|
||||
|
||||
create: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
element: element,
|
||||
tag: 'li', // assumes li children, override with tag: 'tagname'
|
||||
dropOnEmpty: false,
|
||||
tree: false,
|
||||
treeTag: 'ul',
|
||||
overlap: 'vertical', // one of 'vertical', 'horizontal'
|
||||
constraint: 'vertical', // one of 'vertical', 'horizontal', false
|
||||
containment: element, // also takes array of elements (or id's); or false
|
||||
handle: false, // or a CSS class
|
||||
only: false,
|
||||
delay: 0,
|
||||
hoverclass: null,
|
||||
ghosting: false,
|
||||
quiet: false,
|
||||
scroll: false,
|
||||
scrollSensitivity: 20,
|
||||
scrollSpeed: 15,
|
||||
format: this.SERIALIZE_RULE,
|
||||
|
||||
// these take arrays of elements or ids and can be
|
||||
// used for better initialization performance
|
||||
elements: false,
|
||||
handles: false,
|
||||
|
||||
onChange: Prototype.emptyFunction,
|
||||
onUpdate: Prototype.emptyFunction
|
||||
}, arguments[1] || { });
|
||||
|
||||
// clear any old sortable with same element
|
||||
this.destroy(element);
|
||||
|
||||
// build options for the draggables
|
||||
var options_for_draggable = {
|
||||
revert: true,
|
||||
quiet: options.quiet,
|
||||
scroll: options.scroll,
|
||||
scrollSpeed: options.scrollSpeed,
|
||||
scrollSensitivity: options.scrollSensitivity,
|
||||
delay: options.delay,
|
||||
ghosting: options.ghosting,
|
||||
constraint: options.constraint,
|
||||
handle: options.handle };
|
||||
|
||||
if(options.starteffect)
|
||||
options_for_draggable.starteffect = options.starteffect;
|
||||
|
||||
if(options.reverteffect)
|
||||
options_for_draggable.reverteffect = options.reverteffect;
|
||||
else
|
||||
if(options.ghosting) options_for_draggable.reverteffect = function(element) {
|
||||
element.style.top = 0;
|
||||
element.style.left = 0;
|
||||
};
|
||||
|
||||
if(options.endeffect)
|
||||
options_for_draggable.endeffect = options.endeffect;
|
||||
|
||||
if(options.zindex)
|
||||
options_for_draggable.zindex = options.zindex;
|
||||
|
||||
// build options for the droppables
|
||||
var options_for_droppable = {
|
||||
overlap: options.overlap,
|
||||
containment: options.containment,
|
||||
tree: options.tree,
|
||||
hoverclass: options.hoverclass,
|
||||
onHover: Sortable.onHover
|
||||
};
|
||||
|
||||
var options_for_tree = {
|
||||
onHover: Sortable.onEmptyHover,
|
||||
overlap: options.overlap,
|
||||
containment: options.containment,
|
||||
hoverclass: options.hoverclass
|
||||
};
|
||||
|
||||
// fix for gecko engine
|
||||
Element.cleanWhitespace(element);
|
||||
|
||||
options.draggables = [];
|
||||
options.droppables = [];
|
||||
|
||||
// drop on empty handling
|
||||
if(options.dropOnEmpty || options.tree) {
|
||||
Droppables.add(element, options_for_tree);
|
||||
options.droppables.push(element);
|
||||
}
|
||||
|
||||
(options.elements || this.findElements(element, options) || []).each( function(e,i) {
|
||||
var handle = options.handles ? $(options.handles[i]) :
|
||||
(options.handle ? $(e).select('.' + options.handle)[0] : e);
|
||||
options.draggables.push(
|
||||
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
|
||||
Droppables.add(e, options_for_droppable);
|
||||
if(options.tree) e.treeNode = element;
|
||||
options.droppables.push(e);
|
||||
});
|
||||
|
||||
if(options.tree) {
|
||||
(Sortable.findTreeElements(element, options) || []).each( function(e) {
|
||||
Droppables.add(e, options_for_tree);
|
||||
e.treeNode = element;
|
||||
options.droppables.push(e);
|
||||
});
|
||||
}
|
||||
|
||||
// keep reference
|
||||
this.sortables[element.id] = options;
|
||||
|
||||
// for onupdate
|
||||
Draggables.addObserver(new SortableObserver(element, options.onUpdate));
|
||||
|
||||
},
|
||||
|
||||
// return all suitable-for-sortable elements in a guaranteed order
|
||||
findElements: function(element, options) {
|
||||
return Element.findChildren(
|
||||
element, options.only, options.tree ? true : false, options.tag);
|
||||
},
|
||||
|
||||
findTreeElements: function(element, options) {
|
||||
return Element.findChildren(
|
||||
element, options.only, options.tree ? true : false, options.treeTag);
|
||||
},
|
||||
|
||||
onHover: function(element, dropon, overlap) {
|
||||
if(Element.isParent(dropon, element)) return;
|
||||
|
||||
if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
|
||||
return;
|
||||
} else if(overlap>0.5) {
|
||||
Sortable.mark(dropon, 'before');
|
||||
if(dropon.previousSibling != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = "hidden"; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, dropon);
|
||||
if(dropon.parentNode!=oldParentNode)
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
Sortable.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
} else {
|
||||
Sortable.mark(dropon, 'after');
|
||||
var nextElement = dropon.nextSibling || null;
|
||||
if(nextElement != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = "hidden"; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, nextElement);
|
||||
if(dropon.parentNode!=oldParentNode)
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
Sortable.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onEmptyHover: function(element, dropon, overlap) {
|
||||
var oldParentNode = element.parentNode;
|
||||
var droponOptions = Sortable.options(dropon);
|
||||
|
||||
if(!Element.isParent(dropon, element)) {
|
||||
var index;
|
||||
|
||||
var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
|
||||
var child = null;
|
||||
|
||||
if(children) {
|
||||
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
|
||||
|
||||
for (index = 0; index < children.length; index += 1) {
|
||||
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
|
||||
offset -= Element.offsetSize (children[index], droponOptions.overlap);
|
||||
} else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
|
||||
child = index + 1 < children.length ? children[index + 1] : null;
|
||||
break;
|
||||
} else {
|
||||
child = children[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropon.insertBefore(element, child);
|
||||
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
droponOptions.onChange(element);
|
||||
}
|
||||
},
|
||||
|
||||
unmark: function() {
|
||||
if(Sortable._marker) Sortable._marker.hide();
|
||||
},
|
||||
|
||||
mark: function(dropon, position) {
|
||||
// mark on ghosting only
|
||||
var sortable = Sortable.options(dropon.parentNode);
|
||||
if(sortable && !sortable.ghosting) return;
|
||||
|
||||
if(!Sortable._marker) {
|
||||
Sortable._marker =
|
||||
($('dropmarker') || Element.extend(document.createElement('DIV'))).
|
||||
hide().addClassName('dropmarker').setStyle({position:'absolute'});
|
||||
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
|
||||
}
|
||||
var offsets = Position.cumulativeOffset(dropon);
|
||||
Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
|
||||
|
||||
if(position=='after')
|
||||
if(sortable.overlap == 'horizontal')
|
||||
Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
|
||||
else
|
||||
Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
|
||||
|
||||
Sortable._marker.show();
|
||||
},
|
||||
|
||||
_tree: function(element, options, parent) {
|
||||
var children = Sortable.findElements(element, options) || [];
|
||||
|
||||
for (var i = 0; i < children.length; ++i) {
|
||||
var match = children[i].id.match(options.format);
|
||||
|
||||
if (!match) continue;
|
||||
|
||||
var child = {
|
||||
id: encodeURIComponent(match ? match[1] : null),
|
||||
element: element,
|
||||
parent: parent,
|
||||
children: [],
|
||||
position: parent.children.length,
|
||||
container: $(children[i]).down(options.treeTag)
|
||||
};
|
||||
|
||||
/* Get the element containing the children and recurse over it */
|
||||
if (child.container)
|
||||
this._tree(child.container, options, child);
|
||||
|
||||
parent.children.push (child);
|
||||
}
|
||||
|
||||
return parent;
|
||||
},
|
||||
|
||||
tree: function(element) {
|
||||
element = $(element);
|
||||
var sortableOptions = this.options(element);
|
||||
var options = Object.extend({
|
||||
tag: sortableOptions.tag,
|
||||
treeTag: sortableOptions.treeTag,
|
||||
only: sortableOptions.only,
|
||||
name: element.id,
|
||||
format: sortableOptions.format
|
||||
}, arguments[1] || { });
|
||||
|
||||
var root = {
|
||||
id: null,
|
||||
parent: null,
|
||||
children: [],
|
||||
container: element,
|
||||
position: 0
|
||||
};
|
||||
|
||||
return Sortable._tree(element, options, root);
|
||||
},
|
||||
|
||||
/* Construct a [i] index for a particular node */
|
||||
_constructIndex: function(node) {
|
||||
var index = '';
|
||||
do {
|
||||
if (node.id) index = '[' + node.position + ']' + index;
|
||||
} while ((node = node.parent) != null);
|
||||
return index;
|
||||
},
|
||||
|
||||
sequence: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend(this.options(element), arguments[1] || { });
|
||||
|
||||
return $(this.findElements(element, options) || []).map( function(item) {
|
||||
return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
|
||||
});
|
||||
},
|
||||
|
||||
setSequence: function(element, new_sequence) {
|
||||
element = $(element);
|
||||
var options = Object.extend(this.options(element), arguments[2] || { });
|
||||
|
||||
var nodeMap = { };
|
||||
this.findElements(element, options).each( function(n) {
|
||||
if (n.id.match(options.format))
|
||||
nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
|
||||
n.parentNode.removeChild(n);
|
||||
});
|
||||
|
||||
new_sequence.each(function(ident) {
|
||||
var n = nodeMap[ident];
|
||||
if (n) {
|
||||
n[1].appendChild(n[0]);
|
||||
delete nodeMap[ident];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
serialize: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend(Sortable.options(element), arguments[1] || { });
|
||||
var name = encodeURIComponent(
|
||||
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
|
||||
|
||||
if (options.tree) {
|
||||
return Sortable.tree(element, arguments[1]).children.map( function (item) {
|
||||
return [name + Sortable._constructIndex(item) + "[id]=" +
|
||||
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
|
||||
}).flatten().join('&');
|
||||
} else {
|
||||
return Sortable.sequence(element, arguments[1]).map( function(item) {
|
||||
return name + "[]=" + encodeURIComponent(item);
|
||||
}).join('&');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns true if child is contained within element
|
||||
Element.isParent = function(child, element) {
|
||||
if (!child.parentNode || child == element) return false;
|
||||
if (child.parentNode == element) return true;
|
||||
return Element.isParent(child.parentNode, element);
|
||||
};
|
||||
|
||||
Element.findChildren = function(element, only, recursive, tagName) {
|
||||
if(!element.hasChildNodes()) return null;
|
||||
tagName = tagName.toUpperCase();
|
||||
if(only) only = [only].flatten();
|
||||
var elements = [];
|
||||
$A(element.childNodes).each( function(e) {
|
||||
if(e.tagName && e.tagName.toUpperCase()==tagName &&
|
||||
(!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
|
||||
elements.push(e);
|
||||
if(recursive) {
|
||||
var grandchildren = Element.findChildren(e, only, recursive, tagName);
|
||||
if(grandchildren) elements.push(grandchildren);
|
||||
}
|
||||
});
|
||||
|
||||
return (elements.length>0 ? elements.flatten() : []);
|
||||
};
|
||||
|
||||
Element.offsetSize = function (element, type) {
|
||||
return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
|
||||
};
|
||||
1128
docs/effects.js
vendored
Normal file
BIN
docs/exposure.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/external.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
docs/floodlight.jpg
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
docs/header_gradient.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
docs/help-top.png
Normal file
|
After Width: | Height: | Size: 786 B |
BIN
docs/history.png
Normal file
|
After Width: | Height: | Size: 322 B |
BIN
docs/house.png
Normal file
|
After Width: | Height: | Size: 806 B |
95
docs/jstoolbar.css
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
.jstEditor {
|
||||
padding-left: 0px;
|
||||
}
|
||||
.jstEditor textarea, .jstEditor iframe {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.jstHandle {
|
||||
height: 10px;
|
||||
font-size: 0.1em;
|
||||
cursor: s-resize;
|
||||
/*background: transparent url(img/resizer.png) no-repeat 45% 50%;*/
|
||||
}
|
||||
|
||||
.jstElements {
|
||||
padding: 3px 3px;
|
||||
}
|
||||
|
||||
.jstElements button {
|
||||
margin-right : 6px;
|
||||
width : 24px;
|
||||
height: 24px;
|
||||
padding: 4px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #ddd;
|
||||
background-color : #f7f7f7;
|
||||
background-position : 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.jstElements button:hover {
|
||||
border-color : #000;
|
||||
}
|
||||
.jstElements button span {
|
||||
display : none;
|
||||
}
|
||||
.jstElements span {
|
||||
display : inline;
|
||||
}
|
||||
|
||||
.jstSpacer {
|
||||
width : 0px;
|
||||
font-size: 1px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.jstElements .help { float: right; margin-right: 1em; padding-top: 8px; font-size: 0.9em; }
|
||||
|
||||
/* Buttons
|
||||
-------------------------------------------------------- */
|
||||
.jstb_strong {
|
||||
background-image: url(../images/jstoolbar/bt_strong.png);
|
||||
}
|
||||
.jstb_em {
|
||||
background-image: url(../images/jstoolbar/bt_em.png);
|
||||
}
|
||||
.jstb_ins {
|
||||
background-image: url(../images/jstoolbar/bt_ins.png);
|
||||
}
|
||||
.jstb_del {
|
||||
background-image: url(../images/jstoolbar/bt_del.png);
|
||||
}
|
||||
.jstb_code {
|
||||
background-image: url(../images/jstoolbar/bt_code.png);
|
||||
}
|
||||
.jstb_h1 {
|
||||
background-image: url(../images/jstoolbar/bt_h1.png);
|
||||
}
|
||||
.jstb_h2 {
|
||||
background-image: url(../images/jstoolbar/bt_h2.png);
|
||||
}
|
||||
.jstb_h3 {
|
||||
background-image: url(../images/jstoolbar/bt_h3.png);
|
||||
}
|
||||
.jstb_ul {
|
||||
background-image: url(../images/jstoolbar/bt_ul.png);
|
||||
}
|
||||
.jstb_ol {
|
||||
background-image: url(../images/jstoolbar/bt_ol.png);
|
||||
}
|
||||
.jstb_bq {
|
||||
background-image: url(../images/jstoolbar/bt_bq.png);
|
||||
}
|
||||
.jstb_unbq {
|
||||
background-image: url(../images/jstoolbar/bt_bq_remove.png);
|
||||
}
|
||||
.jstb_pre {
|
||||
background-image: url(../images/jstoolbar/bt_pre.png);
|
||||
}
|
||||
.jstb_link {
|
||||
background-image: url(../images/jstoolbar/bt_link.png);
|
||||
}
|
||||
.jstb_img {
|
||||
background-image: url(../images/jstoolbar/bt_img.png);
|
||||
}
|
||||
BIN
docs/lightning.png
Normal file
|
After Width: | Height: | Size: 669 B |
BIN
docs/newspaper.png
Normal file
|
After Width: | Height: | Size: 581 B |
BIN
docs/projects.png
Normal file
|
After Width: | Height: | Size: 811 B |
4320
docs/prototype.js
vendored
Normal file
BIN
docs/safe.png
Normal file
|
After Width: | Height: | Size: 623 B |
183
docs/scm.css
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
div.changeset-changes ul { margin: 0; padding: 0; }
|
||||
div.changeset-changes ul > ul { margin-left: 18px; padding: 0; }
|
||||
|
||||
li.change {
|
||||
list-style-type:none;
|
||||
background-image: url(../images/bullet_black.png);
|
||||
background-position: 1px 1px;
|
||||
background-repeat: no-repeat;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
padding-left: 20px;
|
||||
margin: 0;
|
||||
}
|
||||
li.change.folder { background-image: url(../images/folder_open.png); }
|
||||
li.change.folder.change-A { background-image: url(../images/folder_open_add.png); }
|
||||
li.change.folder.change-M { background-image: url(../images/folder_open_orange.png); }
|
||||
li.change.change-A { background-image: url(../images/bullet_add.png); }
|
||||
li.change.change-M { background-image: url(../images/bullet_orange.png); }
|
||||
li.change.change-C { background-image: url(../images/bullet_blue.png); }
|
||||
li.change.change-R { background-image: url(../images/bullet_purple.png); }
|
||||
li.change.change-D { background-image: url(../images/bullet_delete.png); }
|
||||
|
||||
li.change .copied-from { font-style: italic; color: #999; font-size: 0.9em; }
|
||||
li.change .copied-from:before { content: " - "}
|
||||
|
||||
#changes-legend { float: right; font-size: 0.8em; margin: 0; }
|
||||
#changes-legend li { float: left; background-position: 5px 0; }
|
||||
|
||||
table.filecontent { border: 1px solid #ccc; border-collapse: collapse; width:98%; }
|
||||
table.filecontent th { border: 1px solid #ccc; background-color: #eee; }
|
||||
table.filecontent th.filename { background-color: #e4e4d4; text-align: left; padding: 0.2em;}
|
||||
table.filecontent tr.spacing th { text-align:center; }
|
||||
table.filecontent tr.spacing td { height: 0.4em; background: #EAF2F5;}
|
||||
table.filecontent th.line-num {
|
||||
border: 1px solid #d7d7d7;
|
||||
font-size: 0.8em;
|
||||
text-align: right;
|
||||
width: 2%;
|
||||
padding-right: 3px;
|
||||
color: #999;
|
||||
}
|
||||
table.filecontent th.line-num a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
table.filecontent td.line-code pre {
|
||||
white-space: pre-wrap; /* CSS2.1 compliant */
|
||||
white-space: -moz-pre-wrap; /* Mozilla-based browsers */
|
||||
white-space: -o-pre-wrap; /* Opera 7+ */
|
||||
}
|
||||
|
||||
/* 12 different colors for the annonate view */
|
||||
table.annotate tr.bloc-0 {background: #FFFFBF;}
|
||||
table.annotate tr.bloc-1 {background: #EABFFF;}
|
||||
table.annotate tr.bloc-2 {background: #BFFFFF;}
|
||||
table.annotate tr.bloc-3 {background: #FFD9BF;}
|
||||
table.annotate tr.bloc-4 {background: #E6FFBF;}
|
||||
table.annotate tr.bloc-5 {background: #BFCFFF;}
|
||||
table.annotate tr.bloc-6 {background: #FFBFEF;}
|
||||
table.annotate tr.bloc-7 {background: #FFE6BF;}
|
||||
table.annotate tr.bloc-8 {background: #FFE680;}
|
||||
table.annotate tr.bloc-9 {background: #AA80FF;}
|
||||
table.annotate tr.bloc-10 {background: #FFBFDC;}
|
||||
table.annotate tr.bloc-11 {background: #BFE4FF;}
|
||||
|
||||
table.annotate td.revision {
|
||||
text-align: center;
|
||||
width: 2%;
|
||||
padding-left: 1em;
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
table.annotate td.author {
|
||||
text-align: center;
|
||||
border-right: 1px solid #d7d7d7;
|
||||
white-space: nowrap;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
width: 3%;
|
||||
background: inherit;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
table.annotate td.line-code { background-color: #fafafa; }
|
||||
|
||||
div.action_M { background: #fd8 }
|
||||
div.action_D { background: #f88 }
|
||||
div.action_A { background: #bfb }
|
||||
|
||||
/************* Coderay styles *************/
|
||||
|
||||
table.CodeRay {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.CodeRay pre { margin: 0px }
|
||||
|
||||
span.CodeRay { white-space: pre; border: 0px; padding: 2px }
|
||||
|
||||
.CodeRay .no { padding: 0px 4px }
|
||||
.CodeRay .code { }
|
||||
|
||||
ol.CodeRay { font-size: 10pt }
|
||||
ol.CodeRay li { white-space: pre }
|
||||
|
||||
.CodeRay .code pre { overflow: auto }
|
||||
|
||||
.CodeRay .debug { color:white ! important; background:blue ! important; }
|
||||
|
||||
.CodeRay .af { color:#00C }
|
||||
.CodeRay .an { color:#007 }
|
||||
.CodeRay .av { color:#700 }
|
||||
.CodeRay .aw { color:#C00 }
|
||||
.CodeRay .bi { color:#509; font-weight:bold }
|
||||
.CodeRay .c { color:#666; }
|
||||
|
||||
.CodeRay .ch { color:#04D }
|
||||
.CodeRay .ch .k { color:#04D }
|
||||
.CodeRay .ch .dl { color:#039 }
|
||||
|
||||
.CodeRay .cl { color:#B06; font-weight:bold }
|
||||
.CodeRay .co { color:#036; font-weight:bold }
|
||||
.CodeRay .cr { color:#0A0 }
|
||||
.CodeRay .cv { color:#369 }
|
||||
.CodeRay .df { color:#099; font-weight:bold }
|
||||
.CodeRay .di { color:#088; font-weight:bold }
|
||||
.CodeRay .dl { color:black }
|
||||
.CodeRay .do { color:#970 }
|
||||
.CodeRay .ds { color:#D42; font-weight:bold }
|
||||
.CodeRay .e { color:#666; font-weight:bold }
|
||||
.CodeRay .en { color:#800; font-weight:bold }
|
||||
.CodeRay .er { color:#F00; background-color:#FAA }
|
||||
.CodeRay .ex { color:#F00; font-weight:bold }
|
||||
.CodeRay .fl { color:#60E; font-weight:bold }
|
||||
.CodeRay .fu { color:#06B; font-weight:bold }
|
||||
.CodeRay .gv { color:#d70; font-weight:bold }
|
||||
.CodeRay .hx { color:#058; font-weight:bold }
|
||||
.CodeRay .i { color:#00D; font-weight:bold }
|
||||
.CodeRay .ic { color:#B44; font-weight:bold }
|
||||
|
||||
.CodeRay .il { background: #eee }
|
||||
.CodeRay .il .il { background: #ddd }
|
||||
.CodeRay .il .il .il { background: #ccc }
|
||||
.CodeRay .il .idl { font-weight: bold; color: #888 }
|
||||
|
||||
.CodeRay .in { color:#B2B; font-weight:bold }
|
||||
.CodeRay .iv { color:#33B }
|
||||
.CodeRay .la { color:#970; font-weight:bold }
|
||||
.CodeRay .lv { color:#963 }
|
||||
.CodeRay .oc { color:#40E; font-weight:bold }
|
||||
.CodeRay .of { color:#000; font-weight:bold }
|
||||
.CodeRay .op { }
|
||||
.CodeRay .pc { color:#038; font-weight:bold }
|
||||
.CodeRay .pd { color:#369; font-weight:bold }
|
||||
.CodeRay .pp { color:#579 }
|
||||
.CodeRay .pt { color:#339; font-weight:bold }
|
||||
.CodeRay .r { color:#080; font-weight:bold }
|
||||
|
||||
.CodeRay .rx { background-color:#fff0ff }
|
||||
.CodeRay .rx .k { color:#808 }
|
||||
.CodeRay .rx .dl { color:#404 }
|
||||
.CodeRay .rx .mod { color:#C2C }
|
||||
.CodeRay .rx .fu { color:#404; font-weight: bold }
|
||||
|
||||
.CodeRay .s { background-color:#fff0f0 }
|
||||
.CodeRay .s .s { background-color:#ffe0e0 }
|
||||
.CodeRay .s .s .s { background-color:#ffd0d0 }
|
||||
.CodeRay .s .k { color:#D20 }
|
||||
.CodeRay .s .dl { color:#710 }
|
||||
|
||||
.CodeRay .sh { background-color:#f0fff0 }
|
||||
.CodeRay .sh .k { color:#2B2 }
|
||||
.CodeRay .sh .dl { color:#161 }
|
||||
|
||||
.CodeRay .sy { color:#A60 }
|
||||
.CodeRay .sy .k { color:#A60 }
|
||||
.CodeRay .sy .dl { color:#630 }
|
||||
|
||||
.CodeRay .ta { color:#070 }
|
||||
.CodeRay .tf { color:#070; font-weight:bold }
|
||||
.CodeRay .ts { color:#D70; font-weight:bold }
|
||||
.CodeRay .ty { color:#339; font-weight:bold }
|
||||
.CodeRay .v { color:#036 }
|
||||
.CodeRay .xt { color:#444 }
|
||||
4
docs/stylesheet.css
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
.icon-vote-up { background-image: url(../images/arrow_090.png); }
|
||||
.icon-vote-down { background-image: url(../images/arrow_270.png); }
|
||||
span.votes-positive { color: green; font-weight: bold }
|
||||
span.votes-negative { color: red; font-weight: bold }
|
||||
BIN
docs/ticket.png
Normal file
|
After Width: | Height: | Size: 730 B |