-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnw.html
517 lines (505 loc) · 21.8 KB
/
nw.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title> nw - native widgets </title>
<script src="jquery.js"></script>
<script src="jquery-cookie.js"></script>
<script src="jquery-tablesorter.js"></script>
<script src="strftime.js"></script>
<script src="mustache.js"></script>
<script src="config.js"></script>
<script src="main.js"></script>
<link rel="stylesheet" type="text/css" href="templates/reset.css" />
<link rel="stylesheet" type="text/css" href="templates/hack.css" />
<link rel="stylesheet" type="text/css" id="lights_css" />
<script>
var DOCNAME = 'nw'
var PROJECT = 'nw'
//set the lights before rendering starts
set_lights()
</script>
</head>
<body>
<header>
<div class="container">
<div class="btn-container btn-lights-container">
<a href="#" class="btn btn-lights" id="lights">lights</a>
</div>
<div class="btn-container btn-home-container">
<a href="/" class="btn btn-home">luapower</a>
</div>
<table id="header_table">
<tr>
<td style="vertical-align: middle;" width="100%">
<h1> nw </h1>
<h2> native widgets </h2>
</td>
<td style="vertical-align: middle;" align="right" style="height: 150px">
<table><tr><td>
<div class="doc" id="package_info_container">
<div id="package_info"> </div>
<div id="commit_log"> </div>
</div>
<a href="https://github.com/luapower/nw" class="btn btn-rightside btn-github"><span class="icon"></span>View on GitHub</a>
</td></tr><tr><td>
<a href="https://github.com/luapower/nw/tarball/master" class="btn btn-rightside">Download as .tar.gz</a>
</td></tr><tr><td>
<a href="https://github.com/luapower/nw/zipball/master" class="btn btn-rightside">Download as .zip</a>
</td></tr></table>
</td>
</tr>
</table>
<div class="btn-container btn-discuss-container">
<a href="https://github.com/luapower/nw/issues/new" target="_blank"
class="btn btn-rightside btn-discuss"><span class="icon"></span>Discuss</a>
</div>
</div>
</header>
<div class="bg-container">
<div class="bg-center-container">
<div class="bg bg-nw" style="background-image: url('bg/nw.png');"></div>
</div>
</div>
<div class="under-header">
<div class="container">
<div id="toc_container" class="toc_container doc"></div>
<button id=tab1_button class="tab_button hidden">Documentation</button>
<button id=tab2_button class="tab_button hidden">Package Info</button>
<div id="tabs_cointainer">
<div id="tab1_container">
<section class="doc">
<span id="module_info"></span>
<h4 id="note-work-in-progress-to-be-released-soon">NOTE: work-in-progress (to-be-released soon)</h4>
<h2 id="local-nw-requirenw"><code>local nw = require'nw'</code></h2>
<p>Cross-platform library for displaying and manipulating native windows, drawing in their client area using <a href="cairo.html">cairo</a> or <a href="opengl.html">opengl</a>, and accessing keyboard, mouse and touchpad events in a consistent and well-specified manner across Windows, Linux and OS X.</p>
<p>Jump to: <a href="#quick-example">Quick Example</a> | <a href="#features">Features</a> | <a href="#behavior">Behavior</a></p>
<table>
<tbody>
<tr class="odd">
<td align="left"><strong>application loop</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>nw:app() -> app</code></td>
<td align="left">return the application object (singleton)</td>
</tr>
<tr class="odd">
<td align="left"><code>app:run()</code></td>
<td align="left">run the main loop until the last window is closed</td>
</tr>
<tr class="even">
<td align="left"><code>app:quit()</code></td>
<td align="left">close all windows; abandon on the first window that refuses to close.</td>
</tr>
<tr class="odd">
<td align="left"><strong>displays</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>app:displays() -> iter() -> display</code></td>
<td align="left">get displays in no specific order</td>
</tr>
<tr class="odd">
<td align="left"><code>app:main_display() -> display</code></td>
<td align="left">get the display whose screen rect starts at (0,0)</td>
</tr>
<tr class="even">
<td align="left"><code>app:screen_rect([display]) -> x, y, w, h</code></td>
<td align="left">display's screen rectangle</td>
</tr>
<tr class="odd">
<td align="left"><code>app:desktop_rect([display]) -> x, y, w, h</code></td>
<td align="left">display's screen rectangle excluding the taskbar</td>
</tr>
<tr class="even">
<td align="left"><strong>time</strong></td>
<td align="left"></td>
</tr>
<tr class="odd">
<td align="left"><code>app:time() -> time</code></td>
<td align="left">get an opaque time object representing a hi-resolution timestamp</td>
</tr>
<tr class="even">
<td align="left"><code>app:timediff(time1, time2) -> ms</code></td>
<td align="left">get the difference between two time objects</td>
</tr>
<tr class="odd">
<td align="left"><strong>windows</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>app:windows() -> iter() -> win</code></td>
<td align="left">iterate app's windows in creation order</td>
</tr>
<tr class="odd">
<td align="left"><code>app:active_window() -> win</code></td>
<td align="left">get the active window, if any</td>
</tr>
<tr class="even">
<td align="left"><code>app:window(t) -> win</code></td>
<td align="left">create a window (fields of t below)</td>
</tr>
<tr class="odd">
<td align="left"><strong>state options</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>t.x, t.y, t.w, t.h</code> (required)</td>
<td align="left">window's frame rectangle</td>
</tr>
<tr class="odd">
<td align="left"><code>t.visible</code> (true)</td>
<td align="left">window is visible</td>
</tr>
<tr class="even">
<td align="left"><code>t.title</code> (empty)</td>
<td align="left">window title</td>
</tr>
<tr class="odd">
<td align="left"><code>t.state</code> ('normal')</td>
<td align="left">window state: 'normal', 'maximized', 'minimized'</td>
</tr>
<tr class="even">
<td align="left"><code>t.fullscreen</code> (false)</td>
<td align="left">fullscreen mode (orthogonal to state)</td>
</tr>
<tr class="odd">
<td align="left"><code>t.topmost</code> (false)</td>
<td align="left">always stay on top of all other windows</td>
</tr>
<tr class="even">
<td align="left"><strong>frame options</strong></td>
<td align="left"></td>
</tr>
<tr class="odd">
<td align="left"><code>t.frame</code> (true)</td>
<td align="left">window has a frame, border and title bar</td>
</tr>
<tr class="even">
<td align="left"><code>t.transparent</code> (false)</td>
<td align="left">window is transparent, has no frame and is not directly resizeable</td>
</tr>
<tr class="odd">
<td align="left"><code>t.minimizable</code> (true)</td>
<td align="left">enable the minimize button</td>
</tr>
<tr class="even">
<td align="left"><code>t.maximizable</code> (true)</td>
<td align="left">enable the maximize button</td>
</tr>
<tr class="odd">
<td align="left"><code>t.closeable</code> (true)</td>
<td align="left">enable the close button / allow closing the window</td>
</tr>
<tr class="even">
<td align="left"><code>t.resizeable</code> (true)</td>
<td align="left">window is user-resizeable</td>
</tr>
<tr class="odd">
<td align="left"><strong>window lifetime</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>win:free()</code></td>
<td align="left">close the window and destroy it</td>
</tr>
<tr class="odd">
<td align="left"><code>win:dead() -> true|false</code></td>
<td align="left">check if the window was destroyed</td>
</tr>
<tr class="even">
<td align="left"><code>win:closing()</code></td>
<td align="left">event: closing; return false to prevent it</td>
</tr>
<tr class="odd">
<td align="left"><code>win:closed()</code></td>
<td align="left">event: closed (but not dead yet)</td>
</tr>
<tr class="even">
<td align="left"><strong>window focus</strong></td>
<td align="left"></td>
</tr>
<tr class="odd">
<td align="left"><code>win:activate()</code></td>
<td align="left">activate the window</td>
</tr>
<tr class="even">
<td align="left"><code>win:active() -> true|false</code></td>
<td align="left">check if the window is active</td>
</tr>
<tr class="odd">
<td align="left"><code>win:activated()</code></td>
<td align="left">event: window was activated</td>
</tr>
<tr class="even">
<td align="left"><code>win:deactivated()</code></td>
<td align="left">event: window was deactivated</td>
</tr>
<tr class="odd">
<td align="left"><strong>window state</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>win:show([state])</code></td>
<td align="left">show it, in its current state or in a new state</td>
</tr>
<tr class="odd">
<td align="left"><code>win:hide()</code></td>
<td align="left">hide it (orthogonal to state)</td>
</tr>
<tr class="even">
<td align="left"><code>win:visible([visible]) -> true|false</code></td>
<td align="left">get/set visibility</td>
</tr>
<tr class="odd">
<td align="left"><code>win:state([state]) -> state</code></td>
<td align="left">get/set state: 'normal', 'maximized', 'minimized'</td>
</tr>
<tr class="even">
<td align="left"><code>win:topmost([true]) -> topmost</code></td>
<td align="left">get/set the topmost flag</td>
</tr>
<tr class="odd">
<td align="left"><code>win:fullscreen([on]) -> true|false</code></td>
<td align="left">get/set fullscreen mode (orthogonal to state)</td>
</tr>
<tr class="even">
<td align="left"><code>win:frame_rect([x, y, w, h]) -> x, y, w, h</code></td>
<td align="left">get/set the frame rect of the 'normal' state</td>
</tr>
<tr class="odd">
<td align="left"><code>win:display() -> display</code></td>
<td align="left">the display the window is on</td>
</tr>
<tr class="even">
<td align="left"><code>win:frame_changing(how, x, y, w, h)</code></td>
<td align="left">event: moving (how = 'move'), or resizing (how = 'left', 'right', 'top', 'bottom', 'topleft', 'topright', 'bottomleft', 'bottomright'); return different (x, y, w, h) to constrain</td>
</tr>
<tr class="odd">
<td align="left"><code>win:frame_changed()</code></td>
<td align="left">event: window was moved, resized or state changed</td>
</tr>
<tr class="even">
<td align="left"><code>win:title([title]) -> title</code></td>
<td align="left">get/set the window's title</td>
</tr>
<tr class="odd">
<td align="left"><code>win:save() -> t</code></td>
<td align="left">save user-changeable state</td>
</tr>
<tr class="even">
<td align="left"><code>win:load(t)</code></td>
<td align="left">load user-changeable state</td>
</tr>
<tr class="odd">
<td align="left"><strong>window frame</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>win:frame(flag) -> value</code></td>
<td align="left">get frame flags: 'frame', 'transparent', 'minimizable', 'maximizable', 'closeable', 'resizeable'</td>
</tr>
<tr class="odd">
<td align="left"><strong>keyboard events</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>win:key(keyname) -> down[, toggled]</code></td>
<td align="left">get key and toggle state (see source for key names, or print keys on keydown)</td>
</tr>
<tr class="odd">
<td align="left"><code>win:keydown(key)</code></td>
<td align="left">event: a key was pressed</td>
</tr>
<tr class="even">
<td align="left"><code>win:keyup(key)</code></td>
<td align="left">event: a key was depressed</td>
</tr>
<tr class="odd">
<td align="left"><code>win:keypress(key)</code></td>
<td align="left">event: sent on each key down, including repeats</td>
</tr>
<tr class="even">
<td align="left"><code>win:keychar(char)</code></td>
<td align="left">event: sent after key_press for displayable characters; char is utf-8</td>
</tr>
<tr class="odd">
<td align="left"><strong>mouse events</strong></td>
<td align="left"></td>
</tr>
<tr class="even">
<td align="left"><code>win:hover()</code></td>
<td align="left">event: mouse entered the client area of the window</td>
</tr>
<tr class="odd">
<td align="left"><code>win:leave()</code></td>
<td align="left">event: mouse left the client area of the window</td>
</tr>
<tr class="even">
<td align="left"><code>win:mousemove(x, y)</code></td>
<td align="left">event: mouse move</td>
</tr>
<tr class="odd">
<td align="left"><code>win:mousedown(button)</code></td>
<td align="left">event: a mouse button was pressed: 'left', 'right', 'middle', 'ex1', 'ex2'</td>
</tr>
<tr class="even">
<td align="left"><code>win:mouseup(button)</code></td>
<td align="left">event: a mouse button was depressed</td>
</tr>
<tr class="odd">
<td align="left"><code>win:click(button, count)</code></td>
<td align="left">event: a mouse button was pressed (see notes for double-click)</td>
</tr>
<tr class="even">
<td align="left"><code>win:wheel(delta)</code></td>
<td align="left">event: mouse wheel was moved</td>
</tr>
<tr class="odd">
<td align="left"><code>win:hwheel(delta)</code></td>
<td align="left">event: mouse horizontal wheel was moved</td>
</tr>
<tr class="even">
<td align="left"><strong>mouse state</strong></td>
<td align="left"></td>
</tr>
<tr class="odd">
<td align="left"><code>win.mouse</code></td>
<td align="left">a table with fields: x, y, left, right, middle, xbutton1, xbutton2, inside</td>
</tr>
<tr class="even">
<td align="left"><strong>rendering</strong></td>
<td align="left"></td>
</tr>
<tr class="odd">
<td align="left"><code>win:render(cr)</code></td>
<td align="left">event: redraw the window client area using the given <a href="cairo.html">cairo</a> context</td>
</tr>
<tr class="even">
<td align="left"><code>win:invalidate()</code></td>
<td align="left">request window redrawing</td>
</tr>
<tr class="odd">
<td align="left"><code>win:client_rect() -> x, y, w, h</code></td>
<td align="left">get the client area rect (relative to itself)</td>
</tr>
<tr class="even">
<td align="left"><strong>events</strong></td>
<td align="left"></td>
</tr>
<tr class="odd">
<td align="left"><code>win:event(event, ...)</code></td>
<td align="left">post an event</td>
</tr>
<tr class="even">
<td align="left"><code>win:observe(event, func(...) end)</code></td>
<td align="left">observe an event i.e. call <code>func</code> when <code>event</code> happens</td>
</tr>
<tr class="odd">
<td align="left"><code>app:<event>(win, ...)</code></td>
<td align="left">window events are forwarded to the app object</td>
</tr>
<tr class="even">
<td align="left"><strong>extending</strong></td>
<td align="left"></td>
</tr>
<tr class="odd">
<td align="left"><code>app.window_class</code></td>
<td align="left">the table that windows inherit from</td>
</tr>
<tr class="even">
<td align="left"><code>app.window_class.defaults</code></td>
<td align="left">default values for window creation arguments</td>
</tr>
<tr class="odd">
<td align="left"><code>nw.impl</code></td>
<td align="left">nw implementation class</td>
</tr>
</tbody>
</table>
<h2 id="quick-example">Quick Example</h2>
<pre class="sourceCode lua"><code class="sourceCode lua"><span class="kw">local</span> <span class="kw">nw</span> <span class="ot">=</span> require<span class="st">'nw'</span>
<span class="kw">local</span> <span class="kw">app</span> <span class="ot">=</span> <span class="kw">nw</span>:app<span class="ot">()</span>
<span class="kw">local</span> <span class="kw">win</span> <span class="ot">=</span> <span class="kw">app</span>:window<span class="ot">{</span><span class="kw">x</span> <span class="ot">=</span> <span class="dv">100</span><span class="ot">,</span> <span class="kw">y</span> <span class="ot">=</span> <span class="dv">100</span><span class="ot">,</span> <span class="kw">w</span> <span class="ot">=</span> <span class="dv">400</span><span class="ot">,</span> <span class="kw">h</span> <span class="ot">=</span> <span class="dv">200</span><span class="ot">,</span> <span class="kw">title</span> <span class="ot">=</span> <span class="st">'hello'</span><span class="ot">}</span>
<span class="kw">function</span> <span class="kw">win</span>:click<span class="ot">(</span><span class="kw">button</span><span class="ot">,</span> <span class="kw">count</span><span class="ot">)</span>
<span class="kw">if</span> <span class="kw">button</span> <span class="ot">==</span> <span class="st">'left'</span> <span class="kw">and</span> <span class="kw">count</span> <span class="ot">==</span> <span class="dv">3</span> <span class="kw">then</span> <span class="co">--triple click</span>
<span class="kw">app</span>:quit<span class="ot">()</span>
<span class="kw">end</span>
<span class="kw">end</span>
<span class="kw">function</span> <span class="kw">win</span>:keydown<span class="ot">(</span><span class="kw">key</span><span class="ot">)</span>
<span class="kw">if</span> <span class="kw">key</span> <span class="ot">==</span> <span class="st">'F11'</span> <span class="kw">then</span>
<span class="kw">self</span>:fullscreen<span class="ot">(</span><span class="kw">not</span> <span class="kw">self</span>:fullscreen<span class="ot">())</span>
<span class="kw">end</span>
<span class="kw">end</span>
<span class="kw">app</span>:run<span class="ot">()</span> <span class="co">--start the main loop</span></code></pre>
<h2 id="features">Features</h2>
<ul>
<li>frameless transparent windows</li>
<li>edge snapping</li>
<li>full screen mode</li>
<li>multi-monitor support</li>
<li>complete access to the US keyboard</li>
<li>triple-click events</li>
<li>multi-touch gestures</li>
<li>unicode</li>
</ul>
<h2 id="style">Style</h2>
<ul>
<li>consistent and fully-specified behavior accross all supported platforms</li>
<li>no platform-specific features except for supporting platform idioms</li>
<li>unspecified behavior is a bug</li>
<li>unsupported parameter combinations are errors</li>
<li>properties for state are orthogonal to each other</li>
<li>iterators are stable and with specified order</li>
</ul>
<h2 id="backends">Backends</h2>
<ul>
<li>cocoa: OSX 10.7+</li>
<li>winapi: Windows XP/2000+</li>
</ul>
<h2 id="behavior">Behavior</h2>
<h3 id="state-variables">State variables</h3>
<p>State variables are independent of each other, so a window can be maximized, in full screen mode and hidden all at the same time. Changing the state to 'minimized' won't affect the fact that the window is still hidden, nor that it is in full screen mode. If the window is shown, it will be in full screen mode. Out of full screen mode it will be minimized. Likewise, moving or resizing the window affects the frame rectangle of the 'normal' mode. If the window is maximized, resizing it won't have an immediate effect, but changing the state to 'normal' will show the window in its new size.</p>
<p>Maximizing or restoring a window while visible has the side effect of activating the window, if it's not active already.</p>
<h3 id="closing-windows">Closing windows</h3>
<p>Closing a window destroys it by default. You can prevent that by returning false on the <code>closing</code> event.</p>
<pre class="sourceCode lua"><code class="sourceCode lua"><span class="kw">function</span> <span class="kw">win</span>:closing<span class="ot">()</span>
<span class="kw">self</span>:hide<span class="ot">()</span>
<span class="kw">return</span> <span class="kw">false</span> <span class="co">--prevent destruction</span>
<span class="kw">end</span></code></pre>
<h3 id="closing-the-app">Closing the app</h3>
<p>The <code>app:run()</code> call returns after the last window is destroyed. Because of that, <code>app:quit()</code> only has to close all windows, and it tries to do that in reverse-creation order.</p>
<h3 id="multi-clicks">Multi-clicks</h3>
<p>When the user clicks the mouse repeatedly, with a small enough interval between clicks and over the same target, a counter is incremented. When the interval between two clicks is larger than the threshold or the mouse is moved too far away from the initial target, the counter is reset (i.e. the click-chain is interrupted). Returning true on the <code>click</code> event also resets the counter (i.e. interrupts the click chain).</p>
<p>This allows processing of double-clicks, triple-clicks, or multi-clicks by checking the <code>count</code> argument on the <code>click</code> event. If your app doesn't need to process double-clicks or multi-clicks, you can just ignore the <code>count</code> argument. If it does, you must return true after processing the multi-click event so that the counter is reset.</p>
<p>For instance, if your app supports double-click over some target, you must return true when count is 2, otherwise you might get a count of 3 on the next click sometimes, instead of 1 as expected. If your app supports both double-click and triple-click over a target, you must return true when the count is 3 to break the click chain, but you must not return anything when the count is 2, or you'll never get a count of 3.</p>
<h3 id="corner-cases">Corner cases</h3>
<ul>
<li>calling any method on a closed window results in error, except for win:free() which does nothing.</li>
<li>calling app:run() while running is a no op.</li>
<li>app:windows() can return dead windows (but not new windows).</li>
<li>calling display functions on an invalid display object results in error (monitors can come and go too you know).</li>
</ul>
</section>
</div>
<div id="tab2_container" class="doc"></div>
</div>
</div>
<div class="container">
<footer>
<div id="disqus_thread"></div>
<div class="faint">[email protected] | <a href="http://unlicense.org/">public domain</a></div>
</footer>
</div>
</div>
<script type="text/x-mustache" id=info_tab_template>
<h3>Modules</h3>
<ul>
{{#module_array}}
<li>{{name}}</li>
{{/module_array}}
</ul>
</script>
</body>
</html>