diff options
Diffstat (limited to 'static')
-rw-r--r-- | static/Shoes.icns | bin | 0 -> 34271 bytes | |||
-rw-r--r-- | static/app-icon.png | bin | 0 -> 5591 bytes | |||
-rw-r--r-- | static/avatar.png | bin | 0 -> 1374 bytes | |||
-rw-r--r-- | static/code_highlighter.js | 188 | ||||
-rw-r--r-- | static/code_highlighter_ruby.js | 26 | ||||
-rw-r--r-- | static/icon-debug.png | bin | 0 -> 525 bytes | |||
-rw-r--r-- | static/icon-error.png | bin | 0 -> 701 bytes | |||
-rw-r--r-- | static/icon-info.png | bin | 0 -> 778 bytes | |||
-rw-r--r-- | static/icon-warn.png | bin | 0 -> 666 bytes | |||
-rw-r--r-- | static/listbox_button1.png | bin | 0 -> 392 bytes | |||
-rw-r--r-- | static/listbox_button2.png | bin | 0 -> 420 bytes | |||
-rw-r--r-- | static/man-app.png | bin | 0 -> 10775 bytes | |||
-rw-r--r-- | static/man-builds.png | bin | 0 -> 21491 bytes | |||
-rw-r--r-- | static/man-builds1.png | bin | 0 -> 18226 bytes | |||
-rw-r--r-- | static/man-editor-notepad.png | bin | 0 -> 6580 bytes | |||
-rw-r--r-- | static/man-editor-osx.png | bin | 0 -> 11400 bytes | |||
-rw-r--r-- | static/man-ele-background.png | bin | 0 -> 4902 bytes | |||
-rw-r--r-- | static/man-ele-border.png | bin | 0 -> 6296 bytes | |||
-rw-r--r-- | static/man-ele-button.png | bin | 0 -> 5125 bytes | |||
-rw-r--r-- | static/man-ele-check.png | bin | 0 -> 6042 bytes | |||
-rw-r--r-- | static/man-ele-editbox.png | bin | 0 -> 5308 bytes | |||
-rw-r--r-- | static/man-ele-editline.png | bin | 0 -> 4979 bytes | |||
-rw-r--r-- | static/man-ele-image.png | bin | 0 -> 81127 bytes | |||
-rw-r--r-- | static/man-ele-listbox.png | bin | 0 -> 8100 bytes | |||
-rw-r--r-- | static/man-ele-progress.png | bin | 0 -> 4405 bytes | |||
-rw-r--r-- | static/man-ele-radio.png | bin | 0 -> 6049 bytes | |||
-rw-r--r-- | static/man-ele-shape.png | bin | 0 -> 7225 bytes | |||
-rw-r--r-- | static/man-ele-textblock.png | bin | 0 -> 7672 bytes | |||
-rw-r--r-- | static/man-ele-video.png | bin | 0 -> 157853 bytes | |||
-rw-r--r-- | static/man-intro-dmg.png | bin | 0 -> 23639 bytes | |||
-rw-r--r-- | static/man-intro-exe.png | bin | 0 -> 16531 bytes | |||
-rw-r--r-- | static/man-look-tiger.png | bin | 0 -> 101078 bytes | |||
-rw-r--r-- | static/man-look-ubuntu.png | bin | 0 -> 12692 bytes | |||
-rw-r--r-- | static/man-look-vista.png | bin | 0 -> 6629 bytes | |||
-rw-r--r-- | static/man-run-osx.png | bin | 0 -> 18150 bytes | |||
-rw-r--r-- | static/man-run-vista.png | bin | 0 -> 6724 bytes | |||
-rw-r--r-- | static/man-run-xp.png | bin | 0 -> 4348 bytes | |||
-rw-r--r-- | static/man-shot1.png | bin | 0 -> 14208 bytes | |||
-rw-r--r-- | static/manual-en.txt | 3531 | ||||
-rw-r--r-- | static/manual-ja.txt | 2825 | ||||
-rw-r--r-- | static/manual.css | 167 | ||||
-rw-r--r-- | static/menu-corner1.png | bin | 0 -> 462 bytes | |||
-rw-r--r-- | static/menu-corner2.png | bin | 0 -> 563 bytes | |||
-rw-r--r-- | static/menu-gray.png | bin | 0 -> 148 bytes | |||
-rw-r--r-- | static/menu-left.png | bin | 0 -> 534 bytes | |||
-rw-r--r-- | static/menu-right.png | bin | 0 -> 533 bytes | |||
-rw-r--r-- | static/menu-top.png | bin | 0 -> 335 bytes | |||
-rw-r--r-- | static/shoes-dmg.jpg | bin | 0 -> 35616 bytes | |||
-rw-r--r-- | static/shoes-icon-blue.png | bin | 0 -> 8035 bytes | |||
-rw-r--r-- | static/shoes-icon.png | bin | 0 -> 6771 bytes | |||
-rw-r--r-- | static/shoes-manual-apps.gif | bin | 0 -> 27695 bytes | |||
-rw-r--r-- | static/shoes_main_window.png | bin | 0 -> 54095 bytes | |||
-rw-r--r-- | static/stripe.png | bin | 0 -> 328 bytes | |||
-rw-r--r-- | static/stubs/blank.exe | bin | 0 -> 81920 bytes | |||
-rw-r--r-- | static/stubs/blank.hfz | bin | 0 -> 842 bytes | |||
-rw-r--r-- | static/stubs/blank.run | 375 | ||||
-rw-r--r-- | static/stubs/cocoa-install | bin | 0 -> 64408 bytes | |||
-rw-r--r-- | static/stubs/sh-install | 49 | ||||
-rw-r--r-- | static/stubs/shoes-stub-inject.exe | bin | 0 -> 80384 bytes | |||
-rw-r--r-- | static/stubs/shoes-stub.exe | bin | 0 -> 99840 bytes | |||
-rw-r--r-- | static/tutor-back.png | bin | 0 -> 132 bytes |
61 files changed, 7161 insertions, 0 deletions
diff --git a/static/Shoes.icns b/static/Shoes.icns Binary files differnew file mode 100644 index 0000000..fe60fe3 --- /dev/null +++ b/static/Shoes.icns diff --git a/static/app-icon.png b/static/app-icon.png Binary files differnew file mode 100644 index 0000000..617aa3b --- /dev/null +++ b/static/app-icon.png diff --git a/static/avatar.png b/static/avatar.png Binary files differnew file mode 100644 index 0000000..4e0d64b --- /dev/null +++ b/static/avatar.png diff --git a/static/code_highlighter.js b/static/code_highlighter.js new file mode 100644 index 0000000..ded1839 --- /dev/null +++ b/static/code_highlighter.js @@ -0,0 +1,188 @@ +/* Unobtrustive Code Highlighter By Dan Webb 11/2005 + Version: 0.4 + + Usage: + Add a script tag for this script and any stylesets you need to use + to the page in question, add correct class names to CODE elements, + define CSS styles for elements. That's it! + + Known to work on: + IE 5.5+ PC + Firefox/Mozilla PC/Mac + Opera 7.23 + PC + Safari 2 + + Known to degrade gracefully on: + IE5.0 PC + + Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors + in older browsers use expressions that use lookahead in string format when defining stylesets. + + This script is inspired by star-light by entirely cunning Dean Edwards + http://dean.edwards.name/star-light/. +*/ + +// replace callback support for safari. +if ("a".replace(/a/, function() {return "b"}) != "b") (function(){ + var default_replace = String.prototype.replace; + String.prototype.replace = function(search,replace){ + // replace is not function + if(typeof replace != "function"){ + return default_replace.apply(this,arguments) + } + var str = "" + this; + var callback = replace; + // search string is not RegExp + if(!(search instanceof RegExp)){ + var idx = str.indexOf(search); + return ( + idx == -1 ? str : + default_replace.apply(str,[search,callback(search, idx, str)]) + ) + } + var reg = search; + var result = []; + var lastidx = reg.lastIndex; + var re; + while((re = reg.exec(str)) != null){ + var idx = re.index; + var args = re.concat(idx, str); + result.push( + str.slice(lastidx,idx), + callback.apply(null,args).toString() + ); + if(!reg.global){ + lastidx += RegExp.lastMatch.length; + break + }else{ + lastidx = reg.lastIndex; + } + } + result.push(str.slice(lastidx)); + return result.join("") + } +})(); + +var CodeHighlighter = { styleSets : new Array }; + +CodeHighlighter.addStyle = function(name, rules) { + // using push test to disallow older browsers from adding styleSets + if ([].push) this.styleSets.push({ + name : name, + rules : rules, + ignoreCase : arguments[2] || false + }) + + function setEvent() { + // set highlighter to run on load (use LowPro if present) + if (typeof Event != 'undefined' && typeof Event.onReady == 'function') + return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter)); + + var old = window.onload; + + if (typeof window.onload != 'function') { + window.onload = function() { CodeHighlighter.init() }; + } else { + window.onload = function() { + old(); + CodeHighlighter.init(); + } + } + } + + // only set the event when the first style is added + if (this.styleSets.length==1) setEvent(); +} + +CodeHighlighter.init = function() { + if (!document.getElementsByTagName) return; + if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function + // throw out older browsers + + var codeEls = document.getElementsByTagName("CODE"); + // collect array of all pre elements + codeEls.filter = function(f) { + var a = new Array; + for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i]; + return a; + } + + var rules = new Array; + rules.toString = function() { + // joins regexes into one big parallel regex + var exps = new Array; + for (var i = 0; i < this.length; i++) exps.push(this[i].exp); + return exps.join("|"); + } + + function addRule(className, rule) { + // add a replace rule + var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp; + // converts regex rules to strings and chops of the slashes + rules.push({ + className : className, + exp : "(" + exp + ")", + length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule + replacement : rule.replacement || null + }); + } + + function parse(text, ignoreCase) { + // main text parsing and replacement + return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() { + var i = 0, j = 1, rule; + while (rule = rules[i++]) { + if (arguments[j]) { + // if no custom replacement defined do the simple replacement + if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>"; + else { + // replace $0 with the className then do normal replaces + var str = rule.replacement.replace("$0", rule.className); + for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]); + return str; + } + } else j+= rule.length; + } + }); + } + + function highlightCode(styleSet) { + // clear rules array + var parsed, clsRx = new RegExp("(\\s|^)" + styleSet.name + "(\\s|$)"); + rules.length = 0; + + // get stylable elements by filtering out all code elements without the correct className + var stylableEls = codeEls.filter(function(item) { return clsRx.test(item.className) }); + + // add style rules to parser + for (var className in styleSet.rules) addRule(className, styleSet.rules[className]); + + + // replace for all elements + for (var i = 0; i < stylableEls.length; i++) { + // EVIL hack to fix IE whitespace badness if it's inside a <pre> + if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') { + stylableEls[i] = stylableEls[i].parentNode; + + parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() { + return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>" + }); + parsed = parsed.replace(/\n( *)/g, function() { + var spaces = ""; + for (var i = 0; i < arguments[1].length; i++) spaces+= " "; + return "\n" + spaces; + }); + parsed = parsed.replace(/\t/g, " "); + parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>"); + + } else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase); + + stylableEls[i].innerHTML = parsed; + } + } + + // run highlighter on all stylesets + for (var i=0; i < this.styleSets.length; i++) { + highlightCode(this.styleSets[i]); + } +} diff --git a/static/code_highlighter_ruby.js b/static/code_highlighter_ruby.js new file mode 100644 index 0000000..e603118 --- /dev/null +++ b/static/code_highlighter_ruby.js @@ -0,0 +1,26 @@ +CodeHighlighter.addStyle("rb",{ + comment : { + exp : /#[^\n]+/ + }, + brackets : { + exp : /\(|\)|\{|\}/ + }, + string : { + exp : /'[^']*'|"[^"]*"/ + }, + keywords : { + exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|raise)\b/ + }, + constant : { + exp : /\b([A-Z]\w+)\b/ + }, + ivar : { + exp : /([^@])(@{1,2}\w+)\b/ + }, + ns : { + exp : /(:{2,})/ + }, + symbol : { + exp : /(:[A-Za-z0-9_!?]+)/ + } +}); diff --git a/static/icon-debug.png b/static/icon-debug.png Binary files differnew file mode 100644 index 0000000..b3d8ce0 --- /dev/null +++ b/static/icon-debug.png diff --git a/static/icon-error.png b/static/icon-error.png Binary files differnew file mode 100644 index 0000000..c37bd06 --- /dev/null +++ b/static/icon-error.png diff --git a/static/icon-info.png b/static/icon-info.png Binary files differnew file mode 100644 index 0000000..12cd1ae --- /dev/null +++ b/static/icon-info.png diff --git a/static/icon-warn.png b/static/icon-warn.png Binary files differnew file mode 100644 index 0000000..628cf2d --- /dev/null +++ b/static/icon-warn.png diff --git a/static/listbox_button1.png b/static/listbox_button1.png Binary files differnew file mode 100644 index 0000000..985b233 --- /dev/null +++ b/static/listbox_button1.png diff --git a/static/listbox_button2.png b/static/listbox_button2.png Binary files differnew file mode 100644 index 0000000..4e2b005 --- /dev/null +++ b/static/listbox_button2.png diff --git a/static/man-app.png b/static/man-app.png Binary files differnew file mode 100644 index 0000000..27f6321 --- /dev/null +++ b/static/man-app.png diff --git a/static/man-builds.png b/static/man-builds.png Binary files differnew file mode 100644 index 0000000..1d3eafb --- /dev/null +++ b/static/man-builds.png diff --git a/static/man-builds1.png b/static/man-builds1.png Binary files differnew file mode 100644 index 0000000..4230778 --- /dev/null +++ b/static/man-builds1.png diff --git a/static/man-editor-notepad.png b/static/man-editor-notepad.png Binary files differnew file mode 100644 index 0000000..165012f --- /dev/null +++ b/static/man-editor-notepad.png diff --git a/static/man-editor-osx.png b/static/man-editor-osx.png Binary files differnew file mode 100644 index 0000000..7d7f5d6 --- /dev/null +++ b/static/man-editor-osx.png diff --git a/static/man-ele-background.png b/static/man-ele-background.png Binary files differnew file mode 100644 index 0000000..af18a7e --- /dev/null +++ b/static/man-ele-background.png diff --git a/static/man-ele-border.png b/static/man-ele-border.png Binary files differnew file mode 100644 index 0000000..9d7c3eb --- /dev/null +++ b/static/man-ele-border.png diff --git a/static/man-ele-button.png b/static/man-ele-button.png Binary files differnew file mode 100644 index 0000000..2f4c662 --- /dev/null +++ b/static/man-ele-button.png diff --git a/static/man-ele-check.png b/static/man-ele-check.png Binary files differnew file mode 100644 index 0000000..a33b9b3 --- /dev/null +++ b/static/man-ele-check.png diff --git a/static/man-ele-editbox.png b/static/man-ele-editbox.png Binary files differnew file mode 100644 index 0000000..5e4ed3c --- /dev/null +++ b/static/man-ele-editbox.png diff --git a/static/man-ele-editline.png b/static/man-ele-editline.png Binary files differnew file mode 100644 index 0000000..784b2aa --- /dev/null +++ b/static/man-ele-editline.png diff --git a/static/man-ele-image.png b/static/man-ele-image.png Binary files differnew file mode 100644 index 0000000..0209fa2 --- /dev/null +++ b/static/man-ele-image.png diff --git a/static/man-ele-listbox.png b/static/man-ele-listbox.png Binary files differnew file mode 100644 index 0000000..785ba5f --- /dev/null +++ b/static/man-ele-listbox.png diff --git a/static/man-ele-progress.png b/static/man-ele-progress.png Binary files differnew file mode 100644 index 0000000..0e95a86 --- /dev/null +++ b/static/man-ele-progress.png diff --git a/static/man-ele-radio.png b/static/man-ele-radio.png Binary files differnew file mode 100644 index 0000000..c16bcd5 --- /dev/null +++ b/static/man-ele-radio.png diff --git a/static/man-ele-shape.png b/static/man-ele-shape.png Binary files differnew file mode 100644 index 0000000..a014d06 --- /dev/null +++ b/static/man-ele-shape.png diff --git a/static/man-ele-textblock.png b/static/man-ele-textblock.png Binary files differnew file mode 100644 index 0000000..4c14217 --- /dev/null +++ b/static/man-ele-textblock.png diff --git a/static/man-ele-video.png b/static/man-ele-video.png Binary files differnew file mode 100644 index 0000000..86a016a --- /dev/null +++ b/static/man-ele-video.png diff --git a/static/man-intro-dmg.png b/static/man-intro-dmg.png Binary files differnew file mode 100644 index 0000000..a63f388 --- /dev/null +++ b/static/man-intro-dmg.png diff --git a/static/man-intro-exe.png b/static/man-intro-exe.png Binary files differnew file mode 100644 index 0000000..0e747b9 --- /dev/null +++ b/static/man-intro-exe.png diff --git a/static/man-look-tiger.png b/static/man-look-tiger.png Binary files differnew file mode 100644 index 0000000..f086593 --- /dev/null +++ b/static/man-look-tiger.png diff --git a/static/man-look-ubuntu.png b/static/man-look-ubuntu.png Binary files differnew file mode 100644 index 0000000..e5470e5 --- /dev/null +++ b/static/man-look-ubuntu.png diff --git a/static/man-look-vista.png b/static/man-look-vista.png Binary files differnew file mode 100644 index 0000000..442564e --- /dev/null +++ b/static/man-look-vista.png diff --git a/static/man-run-osx.png b/static/man-run-osx.png Binary files differnew file mode 100644 index 0000000..31b80c2 --- /dev/null +++ b/static/man-run-osx.png diff --git a/static/man-run-vista.png b/static/man-run-vista.png Binary files differnew file mode 100644 index 0000000..34fcc9b --- /dev/null +++ b/static/man-run-vista.png diff --git a/static/man-run-xp.png b/static/man-run-xp.png Binary files differnew file mode 100644 index 0000000..ee6eedb --- /dev/null +++ b/static/man-run-xp.png diff --git a/static/man-shot1.png b/static/man-shot1.png Binary files differnew file mode 100644 index 0000000..d18a3fa --- /dev/null +++ b/static/man-shot1.png diff --git a/static/manual-en.txt b/static/manual-en.txt new file mode 100644 index 0000000..f452661 --- /dev/null +++ b/static/manual-en.txt @@ -0,0 +1,3531 @@ += Hello! = + +Shoes is a tiny graphics toolkit. It's simple and straightforward. Shoes was +born to be easy! Really, it was made for absolute beginners. There's really +nothing to it. + +You see, the trivial Shoes program can be just one line: + +{{{ + #!ruby + Shoes.app { button("Click me!") { alert("Good job.") } } +}}} + +Shoes programs are written in a language called Ruby. When Shoes is handed +this simple line of Ruby code, a window appears with a button inside reading +"Click me!" When the button is clicked, a message pops up. + +On Linux, here's how this might look: !{:margin_left => 100}man-shot1.png! + +While lots of Shoes apps are graphical games and art programs, you can also +layout text and edit controls easily. !{:margin_left => +40}shoes-manual-apps.gif! + +And, ideally, Shoes programs will run on any of the major platforms out there. +Microsoft Windows, Apple's Mac OS X, Linux and many others. + +^So, welcome to Shoes' built-in manual. This manual is a Shoes program itself!^ + +== Introducing Shoes == + +How does Shoes look on OS X and Windows? Does it really look okay? Is it all +ugly and awkward? People must immediately convulse! It must be so watered down +trying to do everything. + +Well, before getting into the stuff about installing and running Shoes, time to +just check out some screenshots, to give you an idea of what you can do. + +==== Mac OS X ==== + +Shoes runs on Apple Mac OS X Leopard, as well as Tiger. Shoes supports PowerPC +machines as well, however, there is no video support on that platform. +!man-look-tiger.png! + +This is the `simple-sphere.rb` sample running on Tiger. Notice that the app +runs inside a normal OS X window border. + +The whole sphere is drawn with blurred ovals and shadows. You can draw and +animate shapes and apply effects to those shapes in Shoes. + +==== Windows ==== + +Shoes runs on all versions of '''Microsoft Windows XP''', '''Windows Vista''', +'''Windows 7''', and anything else '''Windows 2000''' compatible. +!man-look-vista.png! + +Above is pictured the `simple-clock.rb` sample running on Windows Vista. This +example is also draws ovals and lines to build the clock, which is animated to +repaint itself several times each second. + +Notice the text on the top of the app, showing the current time. Shoes has the +skills to layout words using any color, bold, italics, underlines, and supports +loading fonts from a file. + +==== Linux ==== + +Here's a screenshot of the `simple-downloader.rb` sample running on '''Ubuntu +Linux'''. !man-look-ubuntu.png! + +Notice the buttons and progress bars. These types of controls look different on +OS X and Windows. The text and links would look the same, though. + +Shapes, text, images and videos all look the same on every platforms. However, +native controls (like edit lines and edit boxes) will match the look of the +window theme. Shoes will try to keep native controls all within the size you +give them, only the look will vary. + +== Installing Shoes == + +Okay, on to installing Shoes. I'm sure you're wondering: do I need to install +Ruby? Do I need to unzip anything? What commands do I need to type? + +Nope. You don't need Ruby. You don't need WinZip. Nothing to type. + +On most systems, starting Shoes is just a matter of running the installer and +clicking the Shoes icon. Shoes comes with everything built in. We'll talk +through all the steps, though, just to be clear about it. + +==== Step 1: Installing Shoes ==== + +You'll want to visit [[http://shoes.heroku.com/ the site of Shoes]] to download +the Shoes installer. Usually, you'll just want one of the installers on the +downloads page of the site. !man-builds1.png! + +Here's how to run the installer: + + * On '''Mac OS X''', you'll have a file ending with '''.dmg'''. Double-click this file and a window should appear with a '''Shoes''' icon and an '''Applications''' folder. Following the arrow, drag the Shoes icon into the '''Applications''' folder. !man-intro-dmg.png! + * On '''Windows''', you'll download a '''.exe''' file. Double-click this file and follow the instructions. !man-intro-exe.png! + * On '''Linux''', you'll download a file ending with '''.run'''. Double-click this file and Shoes will start up. (You can also run this file from a prompt as if it was a shell script. In fact, it is a shell script!) + +==== Step 2: Start a New Text File ==== + +Shoes programs are just plain text files ending with a '''.rb''' extension. + +Here are a few ways to create a blank text file: + + * On '''Mac OS X''', visit your '''Applications''' folder and double-click on the '''TextEdit''' app. A blank editor window should come up. Now, go to the '''Format''' menu and select the '''Make Plain Text''' option. Okay, you're all set! !man-editor-osx.png! + * On '''Windows''', go to the Start menu. Select '''All Programs''', then '''Accessories''', then '''Notepad'''. !man-editor-notepad.png! + * On '''Linux''', most distros come with '''gedit'''. You might try running that. Or, if your distro is KDE-based, run '''kate'''. + +Now, in your blank window, type in the following: + +{{{ + Shoes.app do + background "#DFA" + para "Welcome to Shoes" + end +}}} + +Save to your desktop as `welcome.rb`. + +==== Step 3: Run It! Go Shoes! ==== + +To run your program: + + * On '''Mac OS X''', visit your '''Applications''' folder again. This time, double-click the '''Shoes''' icon in that folder. You should see the red shoes icon appear in the dock. Drag your `welcome.rb` from the desktop on to that dock icon. !man-run-osx.png! + * On '''Windows''', get to the Start menu. Go into '''All Programs''', then '''Shoes''', then '''Shoes'''. A file selector box should come up. Browse to your desktop and select `welcome.rb`. Click '''OK''' and you're on your way. !man-run-xp.png! !man-run-vista.png! + * On '''Linux''', run Shoes just like you did in step one. You should see a file selector box. Browse to your desktop, select `welcome.rb` and hit '''OK'''. + +So, not much of a program yet. But it's something! You've got the knack of it, at least! + +==== What Can You Make With Shoes? ==== + +Well, you can make windowing applications. But Shoes is inspired by the web, so +applications tend to use images and text layout rather than a lot of widgets. +For example, Shoes doesn't come with tabbed controls or toolbars. Shoes is a +''tiny'' toolkit, remember? + +Still, Shoes does have a few widgets like buttons and edit boxes. And many +missing elements (like tabbed controls or toolbars) can be simulated with +images. + +Shoes is written in part thanks to a very good art engine called Cairo, which +is used for drawing with shapes and colors. In this way, Shoes is inspired by +NodeBox and Processing, two very good languages for drawing animated graphics. + +== The Rules of Shoes == + +Time to stop guessing how Shoes works. Some of the tricky things will come +back to haunt you. I've boiled down the central rules to Shoes. These are the +things you MUST know to really make it all work. + +These are general rules found throughout Shoes. While Shoes has an overall +philosophy of simplicity and clarity, there are a few points that need to be +studied and remembered. + +==== Shoes Tricky Blocks ==== + +Okay, this is absolutely crucial. Shoes does a trick with blocks. This trick +makes everything easier to read. But it also can make blocks harder to use +once you're in deep. + +'''Let's take a normal Ruby block:''' + +{{{ + ary = ['potion', 'swords', 'shields'] + ary.each do |item| + puts item + end +}}} + +In Shoes, these sorts of blocks work the same. This block above loops through +the array and stores each object in the `item` variable. The `item` variable +disappears (goes out of scope) when the block ends. + +One other thing to keep in mind is that `self` stays the same inside normal +Ruby blocks. Whatever `self` was before the call to `each`, it is the same +inside the `each` block. + +'''Both of these things are also true for most Shoes blocks.''' + +{{{ + Shoes.app do + stack do + para "First" + para "Second" + para "Third" + end + end +}}} + +Here we have two blocks. The first block is sent to `Shoes.app`. This `app` +block changes `self`. + +The other block is the `stack` block. That block does NOT change self. + +'''For what reason does the `app` block change self?''' Let's start by +spelling out that last example completely. + +{{{ + Shoes.app do + self.stack do + self.para "First" + self.para "Second" + self.para "Third" + end + end +}}} + +All of the `self`s in the above example are the App object. Shoes uses Ruby's +`instance_eval` to change self inside the `app` block. So the method calls to +`stack` and `para` get sent to the app. + +'''This also is why you can use instance variables throughout a Shoes app:''' + +{{{ + Shoes.app do + @s = stack do + @p1 = para "First" + @p2 = para "Second" + @p3 = para "Third" + end + end +}}} + +These instance variables will all end up inside the App object. + +'''Whenever you create a new window, `self` is also changed.''' So, this means +the [[Element.window]] and [[Element.dialog]] methods, in addition to +Shoes.app. + +{{{ + Shoes.app :title => "MAIN" do + para self + button "Spawn" do + window :title => "CHILD" do + para self + end + end + end +}}} + +==== Block Redirection ==== + +The `stack` block is a different story, though. It doesn't change `self` and +it's basically a regular block. + +'''But there's a trick:''' when you attach a `stack` and give it a block, the +App object places that stack in its memory. The stack gets popped off when the +block ends. So all drawing inside the block gets '''redirected''' from the +App's top slot to the new stack. + +So those three `para`s will get drawn on the `stack`, even though they actually +get sent to the App object first. + +{{{ + Shoes.app do + stack do + para "First" + para "Second" + para "Third" + end + end +}}} + +A bit tricky, you see? This can bite you even if you know about it. + +One way it'll get you is if you try to edit a stack somewhere else in your +program, outside the `app` block. + +Like let's say you pass around a stack object. And you have a class that edits +that object. + +{{{ + class Messenger + def initialize(stack) + @stack = stack + end + def add(msg) + @stack.append do + para msg + end + end + end +}}} + +So, let's assume you pass the stack object into your Messenger class when the +app starts. And, later, when a message comes in, the `add` method gets used to +append a paragraph to that stack. Should work, right? + +Nope, it won't work. The `para` method won't be found. The App object isn't +around any more. And it's the one with the `para` method. + +Fortunately, each Shoes object has an `app` method that will let you reopen the +App object so you can do somefurther editing. + +{{{ + class Messenger + def initialize(stack) + @stack = stack + end + def add(msg) + @stack.app do + @stack.append do + para msg + end + end + end + end +}}} + +As you can imagine, the `app` object changes `self` to the App object. + +So the rules here are: + +1. '''Methods named "app" or which create new windows alter `self` to the App +object.'''[[BR]](This is true for both Shoes.app and Slot.app, as well as +[[Element.window]] and [[Element.dialog]].)[[BR]] +2. '''Blocks attached to stacks, flows or any manipulation method (such as +append) do not change self. Instead, they pop the slot on to the app's editing +stack.''' + +==== Careful With Fixed Heights ==== + +Fixed widths on slots are great so you can split the window into columns. + +{{{ + Shoes.app do + flow do + stack :width => 200 do + caption "Column one" + para "is 200 pixels wide" + end + stack :width => -200 do + caption "Column two" + para "is 100% minus 200 pixels wide" + end + end + end +}}} + +Fixed heights on slots should be less common. Usually you want your text and +images to just flow down the window as far as they can. Height usually happens +naturally. + +The important thing here is that fixed heights actually force slots to behave +differently. To be sure that the end of the slot is chopped off perfectly, the +slot becomes a '''nested window'''. A new layer is created by the operating +system to keep the slot in a fixed square. + +On difference between normal slots and nested window slots is that the latter +can have scrollbars. + +{{{ + Shoes.app do + stack :width => 200, :height => 200, :scroll => true do + background "#DFA" + 100.times do |i| + para "Paragraph No. #{i}" + end + end + end +}}} + +These nested windows require more memory. They tax the application a bit more. +So if you're experiencing some slowness with hundreds of fixed-height slots, +try a different approach. + +==== Image and Shape Blocks ==== + +Most beginners start littering the window with shapes. It's just easier to +throw all your rectangles and ovals in a slot. + +'''However, bear in mind that Shoes will create objects for all those +shapes!''' + +{{{ + Shoes.app do + fill black(0.1) + 100.times do |i| + oval i, i, i * 2 + end + end +}}} + +In this example, one-hundred Oval objects are created. This isn't too bad. +But things would be slimmer if we made these into a single shape. + +{{{ + Shoes.app do + fill black(0.1) + shape do + 100.times do |i| + oval i, i, i * 2 + end + end + end +}}} + +Oh, wait. The ovals aren't filled in this time! That's because the ovals have +been combined into a single huge shape. And Shoes isn't sure where to fill in +this case. + +So you usually only want to combine into a single shape when you're dealing +strictly with outlines. + +Another option is to combine all those ovals into a single image. + +{{{ + Shoes.app do + fill black(0.1) + image 300, 300 do + 100.times do |i| + oval i, i, i * 2 + end + end + end +}}} + +There we go! The ovals are all combined into a single 300 x 300 pixel image. +In this case, storing that image in memory might be much bigger than having +one-hundred ovals around. But when you're dealing with thousands of shapes, +the image block can be cheaper. + +The point is: it's easy to group shapes together into image or shape blocks, so +give it a try if you're looking to gain some speed. Shape blocks particularly +will save you some memory and speed. + +==== UTF-8 Everywhere ==== + +Ruby itself isn't Unicode aware. And UTF-8 is a type of Unicode. (See +[[http://en.wikipedia.org/wiki/UTF-8 Wikipedia]] for a full explanation of +UTF-8.) + +However, UTF-8 is common on the web. And lots of different platforms support +it. So to cut down on the amount of conversion that Shoes has to do, Shoes +expects all strings to be in UTF-8 format. + +This is great because you can show a myriad of languages (Russian, Japanese, +Spanish, English) using UTF-8 in Shoes. Just be sure that your text editor +uses UTF-8! + +To illustrate: + +{{{ + Shoes.app do + stack :margin => 10 do + @edit = edit_box :width => 1.0 do + @para.text = @edit.text + end + @para = para "" + end + end +}}} + +This app will copy anything you paste into the edit box and display it in a +Shoes paragraph. You can try copying some foreign text (such as Greek or +Japanese) into this box to see how it displays. + +This is a good test because it proves that the edit box gives back UTF-8 +characters. And the paragraph can be set to any UTF-8 characters. + +'''Important note:''' if some UTF-8 characters don't display for you, you will +need to change the paragraph's font. This is especially common on OS X. + +So, a good Japanese font on OS X is '''AppleGothic''' and on Windows is '''MS +UI Gothic'''. + +{{{ + Shoes.app do + para "てすと (te-su-to)", :font => case RUBY_PLATFORM + when /mingw/; "MS UI Gothic" + when /darwin/; "AppleGothic, Arial" + else "Arial" + end + end +}}} + +Again, anything which takes a string in Shoes will need a UTF-8 string. Edit +boxes, edit lines, list boxes, window titles and text blocks all take UTF-8. If +you give a string with bad characters in it, an error will show up in the +console. + +==== The Main App and Its Requires ==== + +'''NOTE:''' This rule is for Raisins. Policeman uses TOPLEVEL_BINDING. So, you +can get `main`, Ruby top-level object, with the first snippet. Although you +need to use `Shoes::Para` instead of `Para` outside `Shoes.app` block. + +Each Shoes app is given a little room where it can create itself. You can +create classes and set variables and they won't be seen by other Shoes +programs. Each program runs inside its own anonymous class. + +{{{ + main = self + Shoes.app do + para main.to_s + end +}}} + +This anonymous class is called `(shoes)` and it's just an empty, unnamed class. +The `Shoes` module is mixed into this class (using `include Shoes`) so that you +can use either `Para` or `Shoes::Para` when referring to the paragraph class. + +The advantages of this approach are: + + * Shoes apps cannot share local variables. + * Classes created in the main app code are temporary. + * The Shoes module can be mixed in to the anonymous class, but not the top-level environment of Ruby itself. + * Garbage collection can clean up apps entirely once they complete. + +The second part is especially important to remember. + +{{{ + class Storage; end + + Shoes.app do + para Storage.new + end +}}} + +The `Storage` class will disappear once the app completes. Other apps aren't +able to use the Storage class. And it can't be gotten to from files that are +loaded using `require`. + +When you `require` code, though, that code will stick around. It will be kept +in the Ruby top-level environment. + +So, the rule is: '''keep your temporary classes in the code with the app and +keep your permanent classes in requires.''' + += Shoes = + +Shoes is all about drawing windows and the stuff inside those windows. Let's +focus on the window itself, for now. The other sections [[Slots]] and +[[Elements]] cover everything that goes inside the window. + +For here on, the manual reads more like a dictionary. Each page is mostly a +list of methods you can use for each topic covered. The idea is to be very +thorough and clear about everything. + +So, if you've hit this far in the manual and you're still hazy about getting +started, you should probably either go back to the [[Hello! beginning]] of the +manual. Or you could try [[http://github.com/shoes/shoes/downloads Nobody Knows +Shoes]], the beginner's leaflet PDF. + +==== Finding Your Way ==== + +This section covers: + + * [[Built-in Built-in methods]] - general methods available anywhere in a Shoes program. + * [[App The App window]] - methods found attached to every main Shoes window. + * [[Styles The Styles Master List]] - a complete list of every style in Shoes. + * [[Classes The Classes list]] - a chart showing what Shoes classes subclass what. + * [[Colors The Colors list]] - a chart of all built-in colors and the [[Built-in.rgb]] numbers for each. + +If you find yourself paging around a lot and not finding something, give the +[[Search]] page a try. It's the quickest way to get around. + +After this general reference, there are two other more specific sections: + + * [[Slots]] - covering [[Element.stack]] and [[Element.flow]], the two types of slots. + * [[Elements]] - documentation for all the buttons, shapes, images, and so on. + +Two really important pages in there are the [[Element Element Creation]] page +(which lists all the elements you can add) and the [[Common Common Methods]] +page (which lists methods you'll find on any slot or element.) + +== Built-in Methods == + +These methods can be used anywhere throughout Shoes programs. + +All of these commands are unusual because you don't attach them with a dot. +'''Every other method in this manual must be attached to an object with a dot.''' +But these are built-in methods (also called: Kernel methods.) Which means no dot! + +A common one is `alert`: + +{{{ + #!ruby + alert "No dots in sight" +}}} + +Compare that to the method `reverse`, which isn't a Kernel method and is only +available for Arrays and Strings: + +{{{ + #!ruby + "Plaster of Paris".reverse + #=> "siraP fo retsalP" + [:dogs, :cows, :snakes].reverse + #=> [:snakes, :cows, :dogs] +}}} + +Most Shoes methods for drawing and making buttons and so on are attached to +slots. See the section on [[Slots]] for more. + +==== Built-in Constants ==== + +Shoes also has a handful of built-in constants which may prove useful if you +are trying to sniff out what release of Shoes is running. + +'''Shoes::RELEASE_NAME''' contains a string with the name of the Shoes release. +All Shoes releases are named, starting with Curious. + +'''Shoes::RELEASE_ID''' contains a number representing the Shoes release. So, +for example, Curious is number 1, as it was the first official release. + +'''Shoes::REVISION''' is the Subversion revision number for this build. + +'''Shoes::FONTS''' is a complete list of fonts available to the app. This list +includes any fonts loaded by the [[Built-in.font]] method. + +=== alert(message: a string) » nil === + +Pops up a window containing a short message. + +{{{ + #!ruby + alert("I'm afraid I must interject!") +}}} + +Please use alerts sparingly, as they are incredibly annoying! If you are using +alerts to show messages to help you debug your program, try checking out the +[[Built-in.debug]] or [[Built-in.info]] methods. + +=== ask(message: a string) » a string === + +Pops up a window and asks a question. For example, you may want to ask someone +their name. + +{{{ + #!ruby + name = ask("Please, enter your name:") +}}} + +When the above script is run, the person at the computer will see a window with +a blank box for entering their name. The name will then be saved in the `name` +variable. + +=== ask_color(title: a string) » Shoes::Color === + +Pops up a color picker window. The program will wait for a color to be picked, +then gives you back a Color object. See the `Color` help for some ways you can +use this color. + +{{{ + #!ruby + backcolor = ask_color("Pick a background") + Shoes.app do + background backcolor + end +}}} + +=== ask_open_file() » a string === + +Pops up an "Open file..." window. It's the standard window which shows all of +your folders and lets you select a file to open. Hands you back the name of the +file. + +{{{ + #!ruby + filename = ask_open_file + Shoes.app do + para File.read(filename) + end +}}} + +=== ask_save_file() » a string === + +Pops up a "Save file..." window, similiar to `ask_open_file`, described +previously. + +{{{ + #!ruby + save_as = ask_save_file +}}} + +=== ask_open_folder() » a string === + +Pops up an "Open folder..." window. It's the standard window which shows all of +your folders and lets you select a folder to open. Hands you back the name of +the folder. + +{{{ + #!ruby + folder = ask_open_folder + Shoes.app do + para Dir.entries(folder) + end +}}} + +=== ask_save_folder() » a string === + +Pops up a "Save folder..." window, similiar to `ask_open_folder`, described +previously. On OS X, this method currently behaves like an alias of +`ask_open_folder`. + +{{{ + #!ruby + save_to = ask_save_folder +}}} + + +=== confirm(question: a string) » true or false === + +Pops up a yes-or-no question. If the person at the computer, clicks '''yes''', +you'll get back a `true`. If not, you'll get back `false`. + +{{{ + #!ruby + if confirm("Draw a circle?") + Shoes.app{ oval :top => 0, :left => 0, :radius => 50 } + end +}}} + +=== debug(message: a string) » nil === + +Sends a debug message to the Shoes console. You can bring up the Shoes console +by pressing `Alt-/` on any Shoes window (or `⌘-/` on OS X.) + +{{{ + #!ruby + debug("Running Shoes on " + RUBY_PLATFORM) +}}} + +Also check out the [[Built-in.error]], [[Built-in.warn]] and [[Built-in.info]] +methods. + +=== error(message: a string) » nil === + +Sends an error message to the Shoes console. This method should only be used +to log errors. Try the [[Built-in.debug]] method for logging messages to +yourself. + +Oh, and, rather than a string, you may also hand exceptions directly to this +method and they'll be formatted appropriately. + +=== exit() === + +Stops your program. Call this anytime you want to suddenly call it quits. + +'''PLEASE NOTE:''' If you need to use Ruby's own `exit` method (like in a +forked Ruby process,) call `Kernel.exit`. + +=== font(message: a string) » an array of font family names === + +Loads a TrueType (or other type of font) from a file. While TrueType is +supported by all platforms, your platform may support other types of fonts. +Shoes uses each operating system's built-in font system to make this work. + +Here's a rough idea of what fonts work on which platforms: + + * Bitmap fonts (.bdf, .pcf, .snf) - Linux + * Font resource (.fon) - Windows + * Windows bitmap font file (.fnt) - Linux, Windows + * PostScript OpenType font (.otf) - Mac OS X, Linux, Windows + * Type1 multiple master (.mmm) - Windows + * Type1 font bits (.pfb) - Linux, Windows + * Type1 font metrics (.pfm) - Linux, Windows + * TrueType font (.ttf) - Mac OS X, Linux, Windows + * TrueType collection (.ttc) - Mac OS X, Linux, Windows + +If the font is properly loaded, you'll get back an array of font names found in +the file. Otherwise, `nil` is returned if no fonts were found in the file. + +Also of interest: the `Shoes::FONTS` constant is a complete list of fonts +available to you on this platform. You can check for a certain font by using +`include?`. + +{{{ + if Shoes::FONTS.include? "Helvetica" + alert "Helvetica is available on this system." + else + alert "You do not have the Helvetica font." + end +}}} + +If you have trouble with fonts showing up, make sure your app loads the font +before it is used. Especially on OS X, if fonts are used before they are +loaded, the font cache will tend to ignore loaded fonts. + +=== gradient(color1, color2) » Shoes::Pattern === + +Builds a linear gradient from two colors. For each color, you may pass in a +Shoes::Color object or a string describing the color. + +=== gray(the numbers: darkness, alpha) » Shoes::Color === + +Create a grayscale color from a level of darkness and, optionally, an alpha +level. + +{{{ + black = gray(0.0) + white = gray(1.0) +}}} + +=== info(message: a string) » nil === + +Logs an informational message to the user in the Shoes console. So, where +debug messages are designed to help the program figure out what's happening, +`info` messages tell the user extra information about the program. + +{{{ + #!ruby + + info("You just ran the info example on Shoes #{Shoes::RELEASE_NAME}.") +}}} + +For example, whenever a Shy file loads, Shoes prints an informational message +in the console describing the author of the Shy and its version. + +=== rgb(a series of numbers: red, green, blue, alpha) » Shoes::Color === + +Create a color from red, green and blue components. An alpha level (indicating +transparency) can also be added, optionally. + +When passing in a whole number, use values from 0 to 255. + +{{{ + blueviolet = rgb(138, 43, 226) + darkgreen = rgb(0, 100, 0) +}}} + +Or, use a decimal number from 0.0 to 1.0. + +{{{ + blueviolet = rgb(0.54, 0.17, 0.89) + darkgreen = rgb(0, 0.4, 0) +}}} + +This method may also be called as `Shoes.rgb`. + +=== warn(message: a string) » nil === + +Logs a warning for the user. A warning is not a catastrophic error (see +[[Built-in.error]] for that.) It is just a notice that the program will be +changing in the future or that certain parts of the program aren't reliable +yet. + +To view warnings and errors, open the Shoes console with `Alt-/` (or `⌘-/` on +OS X.) + +== The App Object == + +An App is a single window running code at a URL. When you switch URLs, a new +App object is created and filled up with stacks, flows and other Shoes +elements. + +The App is the window itself. Which may be closed or cleared and filled with +new elements. !{:margin_left => 100}man-app.png! + +The App itself, in slot/box terminology, is a flow. See the ''Slots'' section +for more, but this just means that any elements placed directly at the +top-level will flow. + +=== Shoes.app(styles) { ... } » Shoes::App === + +Starts up a Shoes app window. This is the starting place for making a Shoes +program. Inside the block, you fill the window with various Shoes elements +(buttons, artwork, etc.) and, outside the block, you use the `styles` to +describe how big the window is. Perhaps also the name of the app or if it's +resizable. + +{{{ + #!ruby + Shoes.app(:title => "White Circle", + :width => 200, :height => 200, :resizable => false) { + background black + fill white + oval :top => 20, :left => 20, :radius => 160 + } +}}} + +In the case above, a small window is built. 200 pixels by 200 pixels. It's +not resizable. And, inside the window, two elements: a black background and a +white circle. + +Once an app is created, it is added to the [[App.Shoes.APPS]] list. If you +want an app to spawn more windows, see the [[Element.window]] method and the +[[Element.dialog]] method. + +=== Shoes.APPS() » An array of Shoes::App objects === + +Builds a complete list of all the Shoes apps that are open right now. Once an +app is closed, it is removed from the list. Yes, you can run many apps at once +in Shoes. It's completely encouraged. + +=== clipboard() » a string === + +Returns a string containing all of the text that's on the system clipboard. +This is the global clipboard that every program on the computer cuts and pastes +into. + +=== clipboard = a string === + +Stores `a string` of text in the system clipboard. + +=== close() === + +Closes the app window. If multiple windows are open and you want to close the +entire application, use the built-in method `exit`. + +=== download(url: a string, styles) === + +Starts a download thread (much like XMLHttpRequest, if you're familiar with +JavaScript.) This method returns immediately and runs the download in the +background. Each download thread also fires `start`, `progress` and `finish` +events. You can send the download to a file or just get back a string (in the +`finish` event.) + +If you attach a block to a download, it'll get called as the `finish` event. + +{{{ + #!ruby + Shoes.app do + stack do + title "Searching Google", :size => 16 + @status = para "One moment..." + + # Search Google for 'shoes' and print the HTTP headers + download "http://www.google.com/search?q=shoes" do |goog| + @status.text = "Headers: " + goog.response.headers.inspect + end + end + end +}}} + +And, if we wanted to use the downloaded data, we'd get it using +`goog.response.body`. This example is truly the simplest form of `download`: +pulling some web data down into memory and handling it once it's done. + +Another simple use of `download` is to save some web data to a file, using the +`:save` style. + +{{{ + #!ruby + Shoes.app do + stack do + title "Downloading Google image", :size => 16 + @status = para "One moment..." + + download "http://www.google.com/logos/nasa50th.gif", + :save => "nasa50th.gif" do + @status.text = "Okay, is downloaded." + end + end + end +}}} + +In this case, you can still get the headers for the downloaded file, but +`response.body` will be `nil`, since the data wasn't saved to memory. You will +need to open the file to get the downloaded goods. + +If you need to send certain headers or actions to the web server, you can use +the `:method`, `:headers` and `:body` styles to customize the HTTP request. +(And, if you need to go beyond these, you can always break out Ruby's OpenURI +class.) + +{{{ + #!ruby + Shoes.app do + stack do + title "GET Google", :size => 16 + @status = para "One moment..." + + download "http://www.google.com/search?q=shoes", + :method => "GET" do |dump| + @status.text = dump.response.body + end + end + end +}}} + +As you can see from the above example, Shoes makes use of the "GET" method to +query google's search engine. + +=== location() » a string === + +Gets a string containing the URL of the current app. + +=== mouse() » an array of numbers: button, left, top === + +Identifies the mouse cursor's location, along with which button is being +pressed. + +{{{ + #!ruby + Shoes.app do + @p = para + animate do + button, left, top = self.mouse + @p.replace "mouse: #{button}, #{left}, #{top}" + end + end +}}} + +=== owner() » Shoes::App === + +Gets the app which launched this app. In most cases, this will be `nil`. But +if this app was launched using the [[Element.window]] method, the owner will be +the app which called `window`. + +=== started?() » true or false === + +Has the window been fully constructed and displayed? This is useful for +threaded code which may try to use the window before it is completely built. +(Also see the `start` event which fires once the window is open.) + +=== visit(url: a string) === + +Changes the location, in order to view a different Shoes URL. + +Absolute URLs (such as http://google.com) are okay, but Shoes will be expecting +a Shoes application to be at that address. (So, google.com won't work, as it's +an HTML app.) + +== The Styles Master List == + +You want to mess with the look of things? Well, throughout Shoes, styles are +used to change the way elements appear. In some cases, you can even style an +entire class of elements. (Like giving all paragraphs a certain font.) + +Styles are easy to spot. They usually show up when the element is created. + +{{{ + Shoes.app :title => "A Styling Sample" do + para "Red with an underline", :stroke => red, :underline => "single" + end +}}} + +Here we've got a `:title` style on the app. And on the paragraph inside the +app, a red `:stroke` style and an `:underline` style. + +The style hash can also be changed by using the [[Common.style]] method, +available on every element and slot. + +{{{ + Shoes.app :title => "A Styling Sample" do + @text = para "Red with an underline" + @text.style(:stroke => red, :underline => "single") + end +}}} + +Most styles can also be set by calling them as methods. (I'd use the manual +search to find the method.) + +{{{ + Shoes.app :title => "A Styling Sample" do + @text = para "Red with an underline" + @text.stroke = red + @text.underline = "single" + end +}}} + +Rather than making you plow through the whole manual to figure out what styles +go where, this helpful page speeds through every style in Shoes and suggests +where that style is used. + +=== :align » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title'' + +The alignment of the text. It is either: + + * "left" - Align the text to the left. + * "center" - Align the text in the center. + * "right" - Align the text to the right. + +=== :angle » a number === + +For: ''background, border, gradient''. + +The angle at which to apply a gradient. Normally, gradient colors range from +top to bottom. If the `:angle` is set to 90, the gradient will rotate 90 +degrees counter-clockwise and the gradient will go from left to right. + +=== :attach » a slot or element === + +For: ''flow, stack''. + +Pins a slot relative to another slot or element. Also, one may write `:attach +=> Window` to position the slot at the window's top, left corner. Taking this +a bit further, the style `:top => 10, :left => 10, :attach => Window` would +place the slot at (10, 10) in the window's coordinates. + +If a slot is attached to an element that moves, the slot will move with it. If +the attachment is reset to `nil`, the slot will flow in with the other objects +that surround, as normal. + +=== :autoplay » true or false === + +For: ''video''. + +Should this video begin playing after it appears? If set to `true`, the video +will start without asking the user. + +=== :bottom » a number === + +For: ''all slots and elements''. + +Sets the pixel coordinate of an element's lower edge. The edge is placed +relative to its container's lower edge. So, `:bottom => 0` will align the +element so that its bottom edge and the bottom edge of its slot touch. + +=== :cap » :curve or :rect or :project === + +For: ''arc, arrow, border, flow, image, mask, rect, star, shape, stack''. + +Sets the shape of the line endpoint, whether curved or square. See the +[[Art.cap]] method for more explanation. + +=== :center » true or false === + +For: ''arc, image, oval, rect, shape''. + +Indicates whether the `:top` and `:left` coordinates refer to the center of the +shape or not. If set to `true`, this is similar to setting the +[[Art.transform]] method to `:center`. + +=== :change » a proc === + +For: ''edit_box, edit_line, list_box''. + +The `change` event handler is stored in this style. See the [[EditBox.change]] +method for the edit_box, as an example. + +=== :checked » true or false === + +For: ''check, radio''. + +Is this checkbox or radio button checked? If set to `true`, the box is +checked. Also see the [[Check.checked=]] method. + +=== :choose » a string === + +For: ''list_box''. + +Sets the currently chosen item in the list. More information at +[[ListBox.choose]]. + +=== :click » a proc === + +For: ''arc, arrow, banner, button, caption, check, flow, image, inscription, +line, link, mask, oval, para, radio, rect, shape, stack, star, subtitle, +tagline, title''. + +The `click` event handler is stored in this style. See the [[Events.click]] +method for a description. + +=== :curve » a number === + +For: ''background, border, rect''. + +The radius of curved corners on each of these rectangular elements. As an +example, if this is set to 6, the corners of the rectangle are given a curve +with a 6-pixel radius. + +=== :displace_left » a number === + +For: ''all slots and elements''. + +Moves a shape, text block or any other kind of object to the left or right. A +positive number displaces to the right by the given number of pixels; a +negative number displaces to the left. Displacing an object doesn't effect the +actual layout of the page. Before using this style, be sure to read the +[[Position.displace]] docs, since its behavior can be a bit surprising. + +=== :displace_top » a number === + +For: ''all slots and elements''. + +Moves a shape, text block or any other kind of object up or down. A positive +number moves the object down by this number of pixels; a negative number moves +it up. Displacing doesn't effect the actual layout of the page or the object's +true coordinates. Read the [[Position.displace]] docs, since its behavior can +be a bit surprising. + +=== :emphasis » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Styles the text with an emphasis (commonly italicized.) + +This style recognizes three possible settings: + + * "normal" - the font is upright. + * "oblique" - the font is slanted, but in a roman style. + * "italic" - the font is slanted in an italic style. + +=== :family » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Styles the text with a given font family. The string should contain the family +name or a comma-separated list of families. + +=== :fill » a hex code, a Shoes::Color or a range of either === + +For: ''arc, arrow, background, banner, caption, code, del, em, flow, image, +ins, inscription, line, link, mask, oval, para, rect, shape, span, stack, star, +strong, sub, sup, subtitle, tagline, title''. + +The color of the background pen. For shapes, this is the fill color, the paint +inside the shape. For text stuffs, this color is painted in the background (as +if marked with a highlighter pen.) + +=== :font » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Styles the text with a font description. The string is pretty flexible, but +can take the form "[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]", where FAMILY-LIST is +a comma separated list of families optionally terminated by a comma, +STYLE_OPTIONS is a whitespace separated list of words where each WORD describes +one of style, variant, weight, stretch, or gravity, and SIZE is a decimal +number (size in points) or optionally followed by the unit modifier "px" for +absolute size. Any one of the options may be absent. If FAMILY-LIST is absent, +then the default font family (Arial) will be used. + +=== :group » a string === + +For: ''radio''. + +Indicates what group a radio button belongs to. Without this setting, radio +buttons are grouped together with other radio buttons in their immediate slot. +"Grouping" radio buttons doesn't mean they'll be grouped next to each other on +the screen. It means that only one radio button from the group can be selected +at a time. + +By giving this style a string, the radio button will be grouped with other +radio buttons that have the same group name. + +=== :height » a number === + +For: ''all slots and elements''. + +Sets the pixel height of this object. If the number is a decimal number, the +height becomes a percentage of its parent's height (with 0.0 being 0% and 1.0 +being 100%.) + +=== :hidden » true or false === + +For: ''all slots and elements''. + +Hides or shows this object. Any object with `:hidden => true` are not +displayed on the screen. Neither are its children. + +=== :inner » a number === + +For: ''star''. + +The size of the inner radius (in pixels.) The inner radius describes the solid +circle within the star where the points begin to separate. + +=== :items » an array === + +For: ''list_box''. + +The list of selections in the list box. See the [[Element.list_box]] method +for an example. + +=== :justify » true or false === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title'' + +Evenly spaces the text horizontally. + +=== :kerning » a number === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Adds to the natural spacing between letters, in pixels. + +=== :leading » a number === + +For: ''banner, caption, inscription, para, subtitle, tagline, title''. + +Sets the spacing between lines in a text block. Defaults to 4 pixels. + +=== :left » a number === + +For: ''all slots and elements''. + +Sets the left coordinate of this object to a specific pixel. Setting `:left => +10` places the object's left edge ten pixels away from the left edge of the +slot containing it. If this style is left unset (or set to `nil`,) the object +will flow in with the other objects surrounding it. + +=== :margin » a number or an array of four numbers === + +For: ''all slots and elements''. + +Margins space an element out from its surroundings. Each element has a left, +top, right, and bottom margin. If the `:margin` style is set to a single +number, the spacing around the element uniformly matches that number. In other +words, if `:margin => 8` is set, all the margins around the element are set to +eight pixels in length. + +This style can also be given an array of four numbers in the form `[left, top, +right, bottom]`. + +=== :margin_bottom » a number === + +For: ''all slots and elements''. + +Sets the bottom margin of the element to a specific pixel size. + +=== :margin_left » a number === + +For: ''all slots and elements''. + +Sets the left margin of the element to a specific pixel size. + +=== :margin_right » a number === + +For: ''all slots and elements''. + +Sets the right margin of the element to a specific pixel size. + +=== :margin_top » a number === + +For: ''all slots and elements''. + +Sets the top margin of the element to a specific pixel size. + +=== :outer » a number === + +For: ''star''. + +Sets the outer radius (half of the ''total'' width) of the star, in pixels. + +=== :points » a number === + +For: ''star''. + +How many points does this star have? A style of `:points => 5` creates a +five-pointed star. + +=== :radius » a number === + +For: ''arc, arrow, background, border, gradient, oval, rect, shape''. + +Sets the radius (half of the diameter or total width) for each of these +elements. Setting this is equivalent to setting both `:width` and `:height` to +double this number. + +=== :right » a number === + +For: ''all slots and elements''. + +Sets the pixel coordinate of an element's right edge. The edge is placed +relative to its container's rightmost edge. So, `:right => 0` will align the +element so that its own right edge and the right edge of its slot touch. +Whereas `:right => 20` will position the right edge of the element off to the +left of its slot's right edge by twenty pixels. + +=== :rise » a number === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Lifts or plunges the font baseline for some text. For example, a +[[Element.sup]] has a `:rise` of 10 pixels. Conversely, the [[Element.sub]] +element has a `:rise` of -10 pixels. + +=== :scroll » true or false === + +For: ''flow, stack''. + +Establishes this slot as a scrolling slot. If `:scroll => true` is set, the +slot will show a scrollbar if any of its contents go past its height. The +scrollbar will appear and disappear as needed. It will also appear inside the +width of the slot, meaning the slot's width will never change, regardless of +whether there is a scrollbar or not. + +=== :secret » true or false === + +For: ''ask, edit_line''. + +Used for password fields, this setting keeps any characters typed in from +becoming visible on the screen. Instead, a replacement character (such as an +asterisk) is show for each letter typed. + +=== :size » a number === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Sets the pixel size for the font used inside this text block or text fragment. + +Font size may also be augmented, through use of the following strings: + + * "xx-small" - 57% of present size. + * "x-small" - 64% of present size. + * "small" - 83% of present size. + * "medium" - no change in size. + * "large" - 120% of present size. + * "x-large" - 143% of present size. + * "xx-large" - 173% of present size. + +=== :state » a string === + +For: ''button, check, edit_box, edit_line, list_box, radio''. + +The `:state` style is for disabling or locking certain controls, if you don't +want them to be edited. + +Here are the possible style settings: + + * nil - the control is active and editable. + * "readonly" - the control is active but cannot be edited. + * "disabled" - the control is not active (grayed out) and cannot be edited. + +=== :stretch » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Sets the font stretching used for a text object. + +Possible settings are: + + * "condensed" - a smaller width of letters. + * "normal" - the standard width of letters. + * "expanded" - a larger width of letters. + +=== :strikecolor » a Shoes::Color === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +The color used to paint any lines stricken through this text. + +=== :strikethrough » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Is this text stricken through? Two options here: + + * "none" - no strikethrough + * "single" - a single-line strikethrough. + +=== :stroke » a hex code, a Shoes::Color or a range of either === + +For: ''arc, arrow, banner, border, caption, code, del, em, flow, image, ins, +inscription, line, link, mask, oval, para, rect, shape, span, stack, star, +strong, sub, sup, subtitle, tagline, title''. + +The color of the foreground pen. In the case of shapes, this is the color the +lines are drawn with. For paragraphs and other text, the letters are printed +in this color. + +=== :strokewidth » a number === + +For: ''arc, arrow, border, flow, image, line, mask, oval, rect, shape, star, stack''. + +The thickness of the stroke, in pixels, of the line defining each of these +shapes. For example, the number two would set the strokewidth to 2 pixels. + +=== :text » a string === + +For: ''button, edit_box, edit_line''. + +Sets the message displayed on a button control, or the contents of an edit_box +or edit_line. + +=== :top » a number === + +For: ''all slots and elements''. + +Sets the top coordinate for an object, relative to its parent slot. If an +object is set with `:top => 40`, this means the object's top edge will be +placed 40 pixels beneath the top edge of the slot that contains it. If no +`:top` style is given, the object is automatically placed in the natural flow +of its slot. + +=== :undercolor » a Shoes::Color === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +The color used to underline text. + +=== :underline » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Dictates the style of underline used in the text. + +The choices for this setting are: + + * "none" - no underline at all. + * "single" - a continuous underline. + * "double" - two continuous parallel underlines. + * "low" - a lower underline, beneath the font baseline. (This is generally recommended only for single characters, particularly when showing keyboard accelerators.) + * "error" - a wavy underline, usually found indicating a misspelling. + +=== :variant » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Vary the font for a group of text. Two choices: + + * "normal" - standard font. + * "smallcaps" - font with the lower case characters replaced by smaller variants of the capital characters. + +=== :weight » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title''. + +Set the boldness of the text. Commonly, this style is set to one of the +following strings: + + * "ultralight" - the ultralight weight (= 200) + * "light" - the light weight (= 300) + * "normal" - the default weight (= 400) + * "semibold" - a weight intermediate between normal and bold (= 600) + * "bold" - the bold weight (= 700) + * "ultrabold" - the ultrabold weight (= 800) + * "heavy" - the heavy weight (= 900) + +However, you may also pass in the numerical weight directly. + +=== :width » a number === + +For: ''all slots and elements''. + +Sets the pixel width for the element. If the number is a decimal, the width is +converted to a percentage (with 0.0 being 0% and 1.0 being 100%.) A width of +100% means the object fills its parent slot. + +=== :wrap » a string === + +For: ''banner, caption, code, del, em, ins, inscription, link, para, span, +strong, sub, sup, subtitle, tagline, title'' + +How should the text wrap when it fills its width? Possible options are: + + * "word" - Break lines at word breaks. + * "char" - Break lines between characters, thus breaking some words. + * "trim" - Cut the line off with an ellipsis if it goes too long. + +== Classes List == + +Here is a complete list of all the classes introduced by Shoes. This chart is +laid out according to how classes inherits from each other. Subclasses are +indented one level to the right, beneath their parent class. + +{INDEX} + +== Colors List == + +The following list of colors can be used throughout Shoes. As background +colors or border colors. As stroke and fill colors. Most of these colors come +from the X11 and HTML palettes. + +All of these colors can be used by name. (So calling the `tomato` method from +inside any slot will get you a nice reddish color.) Below each color, also +find the exact numbers which can be used with the [[Built-in.rgb]] method. + +{COLORS} + += Slots = + +Slots are boxes used to lay out images, text and so on. The two most common +slots are `stacks` and `flows`. Slots can also be referred to as "boxes" or +"canvases" in Shoes terminology. + +Since the mouse wheel and PageUp and PageDown are so pervasive on every +platform, vertical scrolling has really become the only overflow that matters. +So, in Shoes, just as on the web, width is generally fixed. While height goes +on and on. + +Now, you can also just use specific widths and heights for everything, if you +want. That'll take some math, but everything could be perfect. + +Generally, I'd suggest using stacks and flows. The idea here is that you want +to fill up a certain width with things, then advance down the page, filling up +further widths. You can think of these as being analogous to HTML's "block" and +"inline" styles. + +==== Stacks ==== + +A stack is simply a vertical stack of elements. Each element in a stack is +placed directly under the element preceding it. + +A stack is also shaped like a box. So if a stack is given a width of 250, that +stack is itself an element which is 250 pixels wide. + +To create a new stack, use the [[Element.stack]] method, which is available +inside any slot. So stacks can contain other stacks and flows. + +==== Flows ==== + +A flow will pack elements in as tightly as it can. A width will be filled, then +will wrap beneath those elements. Text elements placed next to each other will +appear as a single paragraph. Images and widgets will run together as a series. + +Like the stack, a flow is a box. So stacks and flows can safely be embedded +and, without respect to their contents, are identical. They just treat their +contents differently. + +Making a flow means calling the [[Element.flow]] method. Flows may contain +other flows and stacks. + +Last thing: The Shoes window itself is a flow. + +== Art for Slots == + +Each slot is like a canvas, a blank surface which can be covered with an +assortment of colored shapes or gradients. + +Many common shapes can be drawn with methods like `oval` and `rect`. You'll +need to set up the paintbrush colors first, though. + +The `stroke` command sets the line color. And the `fill` command sets the +color used to paint inside the lines. + +{{{ + #!ruby + Shoes.app do + stroke red + fill blue + oval :top => 10, :left => 10, + :radius => 100 + end +}}} + +That code gives you a blue pie with a red line around it. One-hundred pixels +wide, placed just a few pixels southeast of the window's upper left corner. + +The `blue` and `red` methods above are Color objects. See the section on +Colors for more on how to mix colors. + +==== Inspiration from Processing and NodeBox ==== + +The artful methods generally come verbatim from NodeBox, a drawing kit for +Python. In turn, NodeBox gets much of its ideas from Processing, a Java-like +language for graphics and animation. I owe a great debt to the creators of +these wonderful programs! + +Shoes does a few things differently from NodeBox and Processing. For example, +Shoes has different color methods, including having its own Color objects, +though these are very similar to Processing's color methods. And Shoes also +allows images and gradients to be used for drawing lines and filling in shapes. + +Shoes also borrows some animation ideas from Processing and will continue to +closely consult Processing's methods as it expands. + +=== arc(left, top, width, height, angle1, angle2) » Shoes::Shape === + +Draws an arc shape (a section of an oval) at coordinates (left, top). This +method just give you a bit more control than [[oval]], by offering the +`:angle1` and `:angle2` styles. (In fact, you can mimick the `oval` method by +setting `:angle1` to 0 and `:angle2` to `Shoes::TWO_PI`.) + +=== arrow(left, top, width) » Shoes::Shape === + +Draws an arrow at coordinates (left, top) with a pixel `width`. + +=== cap(:curve or :rect or :project) » self === + +Sets the line cap, which is the shape at the end of every line you draw. If +set to `:curve`, the end is rounded. The default is `:rect`, a line which ends +abruptly flat. The `:project` cap is also fat, but sticks out a bit longer. + +=== fill(pattern) » pattern === + +Sets the fill bucket to a specific color (or pattern.) Patterns can be colors, +gradients or images. So, once the fill bucket is set, you can draw shapes and +they will be colored in with the pattern you've chosen. + +To draw a star with an image pattern: + +{{{ + #!ruby + Shoes.app do + fill "static/avatar.png" + star 200, 200, 5 + end +}}} + +To clear the fill bucket, use `nofill`. And to set the line color (the border +of the star,) use the `stroke` method. + +=== nofill() » self === + +Blanks the fill color, so that any shapes drawn will not be filled in. +Instead, shapes will have only a lining, leaving the middle transparent. + +=== nostroke() » self === + +Empties the line color. Shapes drawn will have no outer line. If `nofill` is +also set, shapes drawn will not be visible. + +=== line(left, top, x2, y2) » Shoes::Shape === + +Draws a line using the current line color (aka "stroke") starting at +coordinates (left, top) and ending at coordinates (x2, y2). + +=== oval(left, top, radius) » Shoes::Shape === + +Draws a circular form at pixel coordinates (left, top) with a width and height +of `radius` pixels. The line and fill colors are used to draw the shape. By +default, the coordinates are for the oval's leftmost, top corner, but this can +be changed by calling the [[Art.transform]] method or by using the `:center` +style on the next method below. + +{{{ + #!ruby + Shoes.app do + stroke blue + strokewidth 4 + fill black + oval 10, 10, 50 + end +}}} + +To draw an oval of varied proportions, you may also use the syntax: `oval(left, top, width, height)`. + +=== oval(styles) » Shoes::Shape === + +Draw circular form using a style hash. The following styles are supported: + + * `top`: the y-coordinate for the oval pen. + * `left`: the x-coordinate for the oval pen. + * `radius`: the width and height of the circle. + * `width`: a specific pixel width for the oval. + * `height`: a specific pixel height for the oval. + * `center`: do the coordinates specific the oval's center? (true or false) + +These styles may also be altered using the `style` method on the Shape object. + +=== rect(top, left, width, height, corners = 0) » Shoes::Shape === + +Draws a rectangle starting from coordinates (top, left) with dimensions of +width x height. Optionally, you may give the rectangle rounded corners with a +fifth argument: the radius of the corners in pixels. + +As with all other shapes, the rectangle is drawn using the stroke and fill colors. + +{{{ + #!ruby + Shoes.app do + stroke rgb(0.5, 0.5, 0.7) + fill rgb(1.0, 1.0, 0.9) + rect 10, 10, self.width - 20, self.height - 20 + end +}}} + +The above sample draws a rectangle which fills the area of its parent box, +leaving a margin of 10 pixels around the edge. Also see the `background` +method for a rectangle which defaults to filling its parent box. + +=== rect(styles) » Shoes::Shape === + +Draw a rectangle using a style hash. The following styles are supported: + + * `top`: the y-coordinate for the rectangle. + * `left`: the x-coordinate for the rectangle. + * `curve`: the pixel radius of the rectangle's corners. + * `width`: a specific pixel width for the rectangle. + * `height`: a specific pixel height for the rectangle. + * `center`: do the coordinates specific the rectangle's center? (true or false) + +These styles may also be altered using the `style` method on the Shape object. + +=== rotate(degrees: a number) » self === + +Rotates the pen used for drawing by a certain number of `degrees`, so that any +shapes will be drawn at that angle. + +In this example below, the rectangle drawn at (30, 30) will be rotated 45 degrees. + +{{{ + #!ruby + Shoes.app do + fill "#333" + rotate 45 + rect 30, 30, 40, 40 + end +}}} + +=== shape(left, top) { ... } » Shoes::Shape === + +Describes an arbitrary shape to draw, beginning at coordinates (left, top) and +continued by calls to `line_to`, `move_to`, `curve_to` and `arc_to` inside the +block. You can look at it as sketching a shape with a long line that curves +and arcs and bends. + +{{{ + #!ruby + Shoes.app do + fill red(0.2) + shape do + move_to(90, 55) + arc_to(50, 55, 50, 50, 0, PI/2) + arc_to(50, 55, 60, 60, PI/2, PI) + arc_to(50, 55, 70, 70, PI, TWO_PI-PI/2) + arc_to(50, 55, 80, 80, TWO_PI-PI/2, TWO_PI) + end + end +}}} + +A shape can also contain other shapes. So, you can place an [[Art.oval]], a +[[Art.rect]], a [[Art.line]], a [[Art.star]] or an [[Art.arrow]] (and all of +the other methods in this [[Art]] section) inside a shape, but they will not be +part of the line. They will be more like a group of shapes are all drawn as +one. + +=== star(left, top, points = 10, outer = 100.0, inner = 50.0) » Shoes::Shape === + +Draws a star using the stroke and fill colors. The star is positioned with its +center point at coordinates (left, top) with a certain number of `points`. The +`outer` width defines the full radius of the star; the `inner` width specifies +the radius of the star's middle, where points stem from. + +=== stroke(pattern) » pattern === + +Set the active line color for this slot. The `pattern` may be a color, a +gradient or an image, all of which are categorized as "patterns." The line +color is then used to draw the borders of any subsequent shape. + +So, to draw an arrow with a red line around it: + +{{{ + #!ruby + Shoes.app do + stroke red + arrow 0, 100, 10 + end +}}} + +To clear the line color, use the `nostroke` method. + +=== strokewidth(a number) » self === + +Sets the line size for all drawing within this slot. Whereas the `stroke` +method alters the line color, the `strokewidth` method alters the line size in +pixels. Calling `strokewidth(4)` will cause lines to be drawn 4 pixels wide. + +=== transform(:center or :corner) » self === + +Should transformations (such as `skew` and `rotate`) be performed around the +center of the shape? Or the corner of the shape? Shoes defaults to `:corner`. + +=== translate(left, top) » self === + +Moves the starting point of the drawing pen for this slot. Normally, the pen +starts at (0, 0) in the top-left corner, so that all shapes are drawn from that +point. With `translate`, if the starting point is moved to (10, 20) and a +shape is drawn at (50, 60), then the shape is actually drawn at (60, 80) on the +slot. + +== Element Creation == + +Shoes has a wide variety of elements, many cherry-picked from HTML. This page +describes how to create these elements in a slot. See the Elements section of +the manual for more on how to modify and use these elements after they have +been placed. + +=== animate(fps) { |frame| ... } » Shoes::Animation === + +Starts an animation timer, which runs parallel to the rest of the app. The +`fps` is a number, the frames per seconds. This number dictates how many times +per second the attached block will be called. + +The block is given a `frame` number. Starting with zero, the `frame` number +tells the block how many frames of the animation have been shown. + +{{{ + #!ruby + Shoes.app do + @counter = para "STARTING" + animate(24) do |frame| + @counter.replace "FRAME #{frame}" + end + end +}}} + +The above animation is shown 24 times per second. If no number is given, the +`fps` defaults to 10. + +=== background(pattern) » Shoes::Background === + +Draws a Background element with a specific color (or pattern.) Patterns can be +colors, gradients or images. Colors and images will tile across the +background. Gradients stretch to fill the background. + +'''PLEASE NOTE:''' Backgrounds are actual elements, not styles. HTML treats +backgrounds like styles. Which means every box can only have one background. +Shoes layers background elements. + +{{{ + #!ruby + Shoes.app do + background black + background white, :width => 50 + end +}}} + +The above example paints two backgrounds. First, a black background is painted +over the entire app's surface area. Then a 50 pixel white stripe is painted +along the left side. + +=== banner(text) » Shoes::Banner === + +Creates a Banner text block. Shoes automatically styles this text to 48 pixels high. + +=== border(text, :strokewidth => a number) » Shoes::Border === + +Draws a Border element using a specific color (or pattern.) Patterns can be +colors, gradients or images. Colors and images will tile across the border. +Gradients stretch to fill the border. + +'''PLEASE NOTE:''' Like Backgrounds, Borders are actual elements, not styles. +HTML treats backgrounds and borders like styles. Which means every box can +only have one borders. Shoes layers border and background elements, along with +text blocks, images, and everything else. + +=== button(text) { ... } » Shoes::Button === + +Adds a push button with the message `text` written across its surface. An +optional block can be attached, which is called if the button is pressed. + +=== caption(text) » Shoes::Caption === + +Creates a Caption text block. Shoes styles this text to 14 pixels high. + +=== check() » Shoes::Check === + +Adds a check box. + +=== code(text) » Shoes::Code === + +Create a Code text fragment. This text defaults to a monospaced font. + +=== del(text) » Shoes::Del === + +Creates a Del text fragment (short for "deleted") which defaults to text with a +single strikethrough in its middle. + +=== dialog(styles) { ... } » Shoes::App === + +Opens a new app window (just like the [[Element.window]] method does,) but the +window is given a dialog box look. + +=== edit_box(text) » Shoes::EditBox === + +Adds a large, multi-line textarea to this slot. The `text` is optional and +should be a string that will start out the box. An optional block can be +attached here which is called any type the user changes the text in the box. + +{{{ + #!ruby + Shoes.app do + edit_box + edit_box "HORRAY EDIT ME" + edit_box "small one", :width => 100, :height => 160 + end +}}} + +=== edit_line(text) » Shoes::EditLine === + +Adds a single-line text box to this slot. The `text` is optional and should be +a string that will start out the box. An optional block can be attached here +which is called any type the user changes the text in the box. + +=== em(text) » Shoes::Em === + +Creates an Em text fragment (short for "emphasized") which, by default, is +styled with italics. + +=== every(seconds) { |count| ... } » Shoes::Every === + +A timer similar to the `animation` method, but much slower. This timer fires a +given number of seconds, running the block attached. So, for example, if you +need to check a web site every five minutes, you'd call `every(300)` with a +block containing the code to actually ping the web site. + +=== flow(styles) { ... } » Shoes::Flow === + +A flow is an invisible box (or "slot") in which you place Shoes elements. Both +flows and stacks are explained in great detail on the main [[Slots]] page. + +Flows organize elements horizontally. Where one would use a [[Element.stack]] +to keep things stacked vertically, a flow places its contents end-to-end across +the page. Once the end of the page is reached, the flow starts a new line of +elements. + +=== image(path) » Shoes::Image === + +Creates an [[Image]] element for displaying a picture. PNG, JPEG and GIF +formats are allowed. + +The `path` can be a file path or a URL. All images loaded are temporarily +cached in memory, but remote images are also cached locally in the user's +personal Shoes directory. Remote images are loaded in the background; as with +browsers, the images will not appear right away, but will be shown when they +are loaded. + +=== imagesize(path) » [width, height] === + +Quickly grab the width and height of an image. The image won't be loaded into +the cache or displayed. + +URGENT NOTE: This method cannot be used with remote images (loaded from HTTP, +rather than the hard drive.) + +=== ins(text) » Shoes::Ins === + +Creates an Ins text fragment (short for "inserted") which Shoes styles with a +single underline. + +=== inscription(text) » Shoes::Inscription === + +Creates an Inscription text block. Shoes styles this text at 10 pixels high. + +=== link(text, :click => proc or string) » Shoes::Link === + +Creates a Link text block, which Shoes styles with a single underline and +colors with a #06E (blue) colored stroke. + +The default LinkHover style is also single-underlined with a #039 (dark blue) stroke. + +=== list_box(:items => [strings, ...]) » Shoes::ListBox === + +Adds a drop-down list box containing entries for everything in the `items` +array. An optional block may be attached, which is called if anything in the +box becomes selected by the user. + +{{{ + #!ruby + Shoes.app do + stack :margin => 10 do + para "Pick a card:" + list_box :items => ["Jack", "Ace", "Joker"] + end + end +}}} + +Call `ListBox#text` to get the selected string. See the `ListBox` section +under `Native` controls for more help. + +=== progress() » Shoes::Progress === + +Adds a progress bar. + +=== para(text) » Shoes::Para === + +Create a Para text block (short for "paragraph") which Shoes styles at 12 +pixels high. + +=== radio(group name: a string or symbol) » Shoes::Radio === + +Adds a radio button. If a `group name` is given, the radio button is +considered part of a group. Among radio buttons in the same group, only one +may be checked. (If no group name is given, the radio button is grouped with +any other radio buttons in the same slot.) + +=== span(text) » Shoes::Span === + +Creates a Span text fragment, unstyled by default. + +=== stack(styles) { ... } » Shoes::Stack === + +Creates a new stack. A stack is a type of slot. (See the main [[Slots]] page +for a full explanation of both stacks and flows.) + +In short, stacks are an invisible box (a "slot") for placing stuff. As you add +things to the stack, such as buttons or images, those things pile up +vertically. Yes, they stack up! + +=== strong(text) » Shoes::Strong === + +Creates a Strong text fragment, styled in bold by default. + +=== sub(text) » Shoes::Sub === + +Creates a Sub text fragment (short for "subscript") which defaults to lowering +the text by 10 pixels and styling it in an x-small font. + +=== subtitle(text) » Shoes::Subtitle === + +Creates a Subtitle text block. Shoes styles this text to 26 pixels high. + +=== sup(text) » Shoes::Sup === + +Creates a Sup text fragment (short for "superscript") which defaults to raising +the text by 10 pixels and styling it in an x-small font. + +=== tagline(text) » Shoes::Tagline === + +Creates a Tagline text block. Shoes styles this text to 18 pixels high. + +=== timer(seconds) { ... } » Shoes::Timer === + +A one-shot timer. If you want to schedule to run some code in a few seconds +(or minutes, hours) you can attach the code as a block here. + +To display an alert box five seconds from now: + +{{{ + #!ruby + Shoes.app do + timer(5) do + alert("Your five seconds are up.") + end + end +}}} + +=== title(text) » Shoes::Title === + +Creates a Title text block. Shoes styles these elements to 34 pixels high. + +=== video(path or url) » Shoes::Video === + +Embeds a movie in this slot. + +=== window(styles) { ... } » Shoes::App === + +Opens a new app window. This method is almost identical to the +[[App.Shoes.app]] method used to start an app in the first place. The +difference is that the `window` method sets the new window's [[App.owner]] +property. (A normal Shoes.app has its `owner` set to `nil`.) + +So, the new window's `owner` will be set to the Shoes::App which launched the +window. This way the child window can call the parent. + +{{{ + #!ruby + Shoes.app :title => "The Owner" do + button "Pop up?" do + window do + para "Okay, popped up from #{owner}" + end + end + end +}}} + +== Events == + +Wondering how to catch stray mouse clicks or keyboard typing? Events are sent +to a slot whenever a mouse moves inside the slot. Or whenever a key is +pressed. Even when the slot is created or destroyed. You can attach a block +to each of these events. + +Mouse events include `motion`, `click`, `hover` and `leave`. Keyboard typing +is represented by the `keypress` event. And the `start` and `finish` events +indicate when a canvas comes into play or is discarded. + +So, let's say you want to change the background of a slot whenever the mouse +floats over it. We can use the `hover` event to change the background when the +mouse comes inside the slot. And `leave` to change back when the mouse floats +away. + +{{{ + #!ruby + Shoes.app do + s = stack :width => 200, :height => 200 do + background red + hover do + s.clear { background blue } + end + leave do + s.clear { background red } + end + end + end +}}} + +=== click { |button, left, top| ... } » self === + +The click block is called when a mouse button is clicked. The `button` is the +number of the mouse button which has been pressed. The `left` and `top` are +the mouse coordinates at which the click happened. + +To catch the moment when the mouse is unclicked, see the [[Events.release]] event. + +=== finish { |self| ... } » self === + +When a slot is removed, it's finish event occurs. The finish block is +immediately handed `self`, the slot object which has been removed. + +=== hover { |self| ... } » self === + +The hover event happens when the mouse enters the slot. The block gets `self`, +meaning the object which was hovered over. + +To catch the mouse exiting the slot, check out the [[Events.leave]] event. + +=== keypress { |key| ... } » self === + +Whenever a key (or combination of keys) is pressed, the block gets called. The +block is sent a `key` which is a string representing the character (such as the +letter or number) on the key. For special keys and key combos, a Ruby symbol +is sent, rather than a string. + +So, for example, if `Shift-a` is pressed, the block will get the string `"A"`. + +However, if the F1 key is pressed, the `:f1` symbol is received. For +`Shift-F1`, the symbol would be `:shift_f1`. + +The modifier keys are `control`, `shift` and `alt`. They appear in that order. +If `Shift-Control-Alt-PgUp` is pressed, the symbol will be +`:control_shift_alt_page_up`. + +One thing about the shift key. You won't see the shift key on most keys. On +US keyboards, `Shift-7` is an ampersand. So you'll get the string `"&"` rather +than `:shift_5`. And, if you press `Shift-Alt-7` on such a keyboard, you'll +get the symbol: `:alt_&`. You'll only see the shift modifier on the special +keys listed a few paragraphs down. + +{{{ + #!ruby + Shoes.app do + @info = para "NO KEY is PRESSED." + keypress do |k| + @info.replace "#{k.inspect} was PRESSED." + end + end +}}} + +Keep in mind that Shoes itself uses a few hotkeys. Alt-Period (`:alt_.`), +Alt-Question (`:alt_?`) and Alt-Slash (`:alt_/`) are reserved for Shoes. + +The list of special keys is as follows: `:escape`, `:delete`, `:backspace`, +`:tab`, `:page_up`, `:page_down`, `:home`, `:end`, `:left`, `:up`, `:right`, +`:down`, `:f1`, `:f2`, `:f3`, `:f4`, `:f5`, `:f6`, `:f7`, `:f8`, `:f9`, `:f10`, +`:f11` and `:f12`. + +One caveat to all of those rules: normally the Return key gives you a string +`"\n"`. When pressed with modifier keys, however, you end up with +`:control_enter`, `:control_alt_enter`, `:shift_alt_enter` and the like. + +=== leave { |self| ... } » self === + +The leave event takes place when the mouse cursor exits a slot. The moment it +no longer is inside the slot's edges. When that takes place, the block is +called with `self`, the slot object which is being left. + +Also see [[Events.hover]] if you'd like to detect the mouse entering a slot. + +=== motion { |left, top| ... } » self === + +The motion block gets called every time the mouse moves around inside the slot. +The block is handed the cursor's `left` and `top` coordinates. + +{{{ + #!ruby + Shoes.app :width => 200, :height => 200 do + background black + fill white + @circ = oval 0, 0, 100, 100 + + motion do |top, left| + @circ.move top - 50, left - 50 + end + end +}}} + +=== release { |button, left, top| ... } » self === + +The release block runs whenever the mouse is unclicked (on mouse up). When the +finger is lifted. The `button` is the number of the button that was depressed. +The `left` and `top` are the coordinates of the mouse at the time the button +was released. + +To catch the actual mouse click, use the [[Events.click]] event. + +=== start { |self| ... } » self === + +The first time the slot is drawn, the start event fires. The block is handed +`self`, the slot object which has just been drawn. + +== Manipulation Blocks == + +The manipulation methods below make quick work of shifting around slots and +inserting new elements. + +=== append() { ... } » self === + +Adds elements to the end of a slot. + +{{{ + #!ruby + Shoes.app do + @slot = stack { para 'Good Morning' } + timer 3 do + @slot.append do + title "Breaking News" + tagline "Astronauts arrested for space shuttle DUI." + end + end + end +}}} + +The `title` and `tagline` elements will be added to the end of the `@slot`. + +=== after(element) { ... } » self === + +Adds elements to a specific place in a slot, just after the `element` which is +a child of the slot. + +=== before(element) { ... } » self === + +Adds elements to a specific place in a slot, just before the `element` which is +a child of the slot. + +=== clear() » self === + +Empties the slot of any elements, timers and nested slots. This is effectively +identical to looping through the contents of the slot and calling each +element's `remove` method. + +=== clear() { ... } » self === + +The clear method also takes an optional block. The block will be used to +replace the contents of the slot. + +{{{ + #!ruby + Shoes.app do + @slot = stack { para "Old text" } + timer 3 do + @slot.clear { para "Brand new text" } + end + end +}}} + +In this example, the "Old text" paragraph will be cleared out, replaced by the +"Brand new text" paragraph. + +=== prepend() { ... } » self === + +Adds elements to the beginning of a slot. + +{{{ + #!ruby + Shoes.app do + @slot = stack { para 'Good Morning' } + timer 3 do + @slot.prepend { para "Your car is ready." } + end + end +}}} + +The `para` element is added to the beginning of the `@slot`. + +== Position of a Slot == + +Like any other element, slots can be styled and customized when they are created. + +To set the width of a stack to 150 pixels: + +{{{ + #!ruby + Shoes.app do + stack(:width => 150) { para "Now that's precision." } + end +}}} + +Each style setting also has a method, which can be used to grab that particular +setting. (So, like, the `width` method returns the width of the slot in +pixels.) + +=== displace(left: a number, top: a number) » self === + +A shortcut method for setting the :displace_left and :displace_top styles. +Displacing is a handy way of moving a slot without altering the layout. In +fact, the `top` and `left` methods will not report displacement at all. So, +generally, displacement is only for temporary animations. For example, +jiggling a button in place. + +The `left` and `top` numbers sent to `displace` are added to the slot's own +top-left coordinates. To subtract from the top-left coordinate, use negative +numbers. + +=== gutter() » a number === + +The size of the scrollbar area. When Shoes needs to show a scrollbar, the +scrollbar may end up covering up some elements that touch the edge of the +window. The `gutter` tells you how many pixels to expect the scrollbar to +cover. + +This is commonly used to pad elements on the right, like so: + +{{{ + #!ruby + Shoes.app do + stack :margin_right => 20 + gutter do + para "Insert fat and ratified declaration of independence here..." + end + end +}}} + +=== height() » a number === + +The vertical size of the viewable slot in pixels. So, if this is a scrolling +slot, you'll need to use `scroll_height()` to get the full size of the slot. + +=== hide() » self === + +Hides the slot, so that it can't be seen. See also [[Position.show]] and [[Position.toggle]]. + +=== left() » a number === + +The left pixel location of the slot. Also known as the x-axis coordinate. + +=== move(left, top) » self === + +Moves the slot to specific coordinates, the (left, top) being the upper left +hand corner of the slot. + +=== remove() » self === + +Removes the slot. It will no longer be displayed and will not be listed in its +parent's contents. It's gone. + +=== scroll() » true or false === + +Is this slot allowed to show a scrollbar? True or false. The scrollbar will +only appear if the height of the slot is also fixed. + +=== scroll_height() » a number === + +The vertical size of the full slot, including any of it which is hidden by scrolling. + +=== scroll_max() » a number === + +The top coordinate which this slot can be scrolled down to. The top coordinate +of a scroll bar is always zero. The bottom coordinate is the full height of +the slot minus one page of scrolling. This bottom coordinate is what +`scroll_max` returns. + +This is basically a shortcut for writing `slot.scroll_height - slot.height`. + +To scroll to the bottom of a slot, use `slot.scroll_top = slot.scroll_max`. + +=== scroll_top() » a number === + +The top coordinate which this slot is scrolled down to. So, if the slot is +scrolled down twenty pixels, this method will return `20`. + +=== scroll_top = a number === + +Scrolls the slot to a certain coordinate. This must be between zero and +`scroll_max`. + +=== show() » self === + +Reveals the slot, if it is hidden. See also [[Position.hide]] and +[[Position.toggle]]. + +=== style() » styles === + +Calling the `style` method with no arguments returns a hash of the styles +presently applied to this slot. + +While methods such as `height` and `width` return the true pixel dimensions of +the slot, you can use `style[:height]` or `style[:width]` to get the dimensions +originally requested. + +{{{ + #!ruby + Shoes.app do + @s = stack :width => "100%" + para @s.style[:width] + end +}}} + +In this example, the paragraph under the stack will display the string "100%". + +=== style(styles) » styles === + +Alter the slot using a hash of style settings. Any of the methods on this page +(aside from this method, of course) can be used as a style setting. So, for +example, there is a `width` method, thus there is also a `width` style. + +{{{ + #!ruby + Shoes.app do + @s = stack { background green } + @s.style(:width => 400, :height => 200) + end +}}} + +=== toggle() » self === + +Hides the slot, if it is shown. Or shows the slot, if it is hidden. + +=== top() » a number === + +The top pixel location of the slot. Also known as the y-axis coordinate. + +=== width() » a number === + +The horizontal size of the slot in pixels. + +== Traversing the Page == + +You may find yourself needing to loop through the elements inside a slot. Or +maybe you need to climb the page, looking for a stack that is the parent of an +element. + +On any element, you may call the `parent` method to get the slot directly above +it. And on slots, you can call the `contents` method to get all of the +children. (Some elements, such as text blocks, also have a `contents` method +for getting their children.) + +=== contents() » an array of elements === + +Lists all elements in a slot. + +=== parent() » a Shoes::Stack or Shoes::Flow === + +Gets the object for this element's container. + += Elements = + +Ah, here's the stuff of Shoes. An element can be as simple as an oval shape. Or +as complex as a video stream. You've encountered all of these elements before +in the Slots section of th manual. + +Shoes has seven native controls: the Button, the EditLine, the EditBox, the +ListBox, the Progress meter, the Check box and the Radio. By "native" +controls, we mean that each of these seven elements is drawn by the operating +system. So, a Progress bar will look one way on Windows and another way on OS +X. + +Shoes also has seven basic other types of elements: Background, Border, Image, +Shape, TextBlock, Timer and Video. These all should look and act the same on +every operating system. + +Once an element is created, you will often still want to change it. To move it +or hide it or get rid of it. You'll use the commands in this section to do that +sort of stuff. (Especially check out the [[Common Common Methods]] section for +commands you can use on any element.) + +So, for example, use the `image` method of a Slot to place a PNG on the screen. +The `image` method gives you back an Image object. Use the methods of the Image +object to change things up. + +== Common Methods == + +A few methods are shared by every little element in Shoes. Moving, showing, +hiding. Removing an element. Basic and very general things. This list +encompasses those common commands. + +One of the most general methods of all is the `style` method (which is also +covered as the [[Position.style]] method for slots.) + +{{{ + #!ruby + Shoes.app do + stack do + # Background, text and a button: both are elements! + @back = background green + @text = banner "A Message for You, Rudy" + @press = button "Stop your messin about!" + + # And so, both can be styled. + @text.style :size => 12, :stroke => red, :margin => 10 + @press.style :width => 400 + @back.style :height => 10 + end + end +}}} + +For specific commands, see the other links to the left in the Elements section. +Like if you want to pause or play a video file, check the [[Video]] section, +since pausing and playing is peculiar to videos. No sense pausing a button. + +=== displace(left: a number, top: a number) » self === + +Displacing an element moves it. But without changing the layout around it. +This is great for subtle animations, especially if you want to reserve a place +for an element while it is still animating. Like maybe a quick button shake or +a slot sliding into view. + +When you displace an element, it moves relative to the upper-left corner where +it was placed. So, if an element is at the coordinates (20, 40) and you +displace it 2 pixels left and 6 pixels on top, you end up with the coordinates +(22, 46). + +{{{ + #!ruby + Shoes.app do + flow :margin => 12 do + # Set up three buttons + button "One" + @two = button "Two" + button "Three" + + # Bounce the second button + animate do |i| + @two.displace(0, (Math.sin(i) * 6).to_i) + end + end + end +}}} + +Notice that while the second button bounces, the other two buttons stay put. +If we used a normal `move` in this situation, the second button would be moved +out of the layout and the buttons would act as if the second button wasn't +there at all. (See the [[Common.move]] example.) + +'''Of particular note:''' if you use the `left` and `top` methods to get the +coordinates of a displaced element, you'll just get back the normal +coordinates. As if there was no displacement. Displacing is just intended for +quick animations! + +=== height() » a number === + +The vertical screen size of the element in pixels. In the case of images, this +is not the full size of the image. This is the height of the element as it is +shown right now. + +If you have a 150x150 pixel image and you set the width to 50 pixels, this +method will return 50. + +Also see the [[Common.width]] method for an example and some other comments. + +=== hide() » self === + +Hides the element, so that it can't be seen. See also [[Common.show]] and +[[Common.toggle]]. + +=== left() » a number === + +Gets you the pixel position of the left edge of the element. + +=== move(left: a number, top: a number) » self === + +Moves the element to a specific pixel position within its slot. The element is +still inside the slot. But it will no longer be stacked or flowed in with the +other stuff in the slot. The element will float freely, now absolutely +positioned instead. + +{{{ + #!ruby + Shoes.app do + flow :margin => 12 do + # Set up three buttons + button "One" + @two = button "Two" + button "Three" + + # Bounce the second button + animate do |i| + @two.move(40, 40 + (Math.sin(i) * 6).to_i) + end + end + end +}}} + +The second button is moved to a specific place, allowing the third button to +slide over into its place. If you want to move an element without shifting +other pieces, see the [[Common.displace]] method. + +=== parent() » a Shoes::Stack or Shoes::Flow === + +Gets the object for this element's container. Also see the slot's +[[Traversing.contents]] to do the opposite: get a container's elements. + +=== remove() » self === + +Removes the element from its slot. (In other words: throws it in the garbage.) +The element will no longer be displayed. + +=== show() » self === + +Reveals the element, if it is hidden. See also [[Common.hide]] and +[[Common.toggle]]. + +=== style() » styles === + +Gives you the full set of styles applied to this element, in the form of a +Hash. While methods like `width` and `height` and `top` give you back specific +pixel dimensions, using `style[:width]` or `style[:top]`, you can get the +original setting (things like "100%" for width or "10px" for top.) + +{{{ + #!ruby + Shoes.app do + # A button which take up the whole page + @b = button "All of it", :width => 1.0, :height => 1.0 + + # When clicked, show the styles + @b.click { alert(@b.style.inspect) } + end +}}} + +=== style(styles) » styles === + +Changes the style of an element. This could include the `:width` and `:height` +of an element, the font `:size` of some text, the `:stroke` and `:fill` of a +shape. Or any other number of style settings. + +=== toggle() » self === + +Hides an element if it is shown. Or shows the element, if it is hidden. + +=== top() » a number === + +Gets the pixel position of the top edge of the element. + +=== width() » a number === + +Gets the pixel width for the full size of the element. This method always +returns an exact pixel size. In the case of images, this is not the full width +of the image, just the size it is shown at. See the [[Common.height]] method +for more. + +Also, if you create an element with a width of 100% and that element is inside +a stack which is 120 pixels wide, you'll get back `120`. However, if you call +`style[:width]`, you'll get `"100%"`. + +{{{ + #!ruby + Shoes.app do + stack :width => 120 do + @b = button "Click me", :width => "100%" do + alert "button.width = #{@b.width}\n" + + "button.style[:width] = #{@b.style[:width]}" + end + end + end +}}} + +In order to set the width, you'll have to go through the [[Common.style]] +method again. So, to set the button to 150 pixels wide: `@b.style(:width => +150)`. + +To let Shoes pick the element's width, go with `@b.style(:width => nil)` to +empty out the setting. + +== Background == + +A background is a color, a gradient or an image that is painted across an +entire slot. Both backgrounds and borders are a type of Shoes::Pattern. +!{:margin_left => 100}man-ele-background.png! + +Even though it's called a ''background'', you may still place this element in +front of other elements. If a background comes after something else painted on +the slot (like a `rect` or an `oval`,) the background will be painted over that +element. + +The simplest background is just a plain color background, created with the +[[Element.background]] method, such as this black background: + +{{{ + #!ruby + Shoes.app do + background black + end +}}} + +A simple background like that paints the entire slot that contains it. (In +this case, the whole window is painted black.) + +You can use styles to cut down the size or move around the background to your liking. + +To paint a black background across the top fifty pixels of the window: + +{{{ + #!ruby + Shoes.app do + background black, :height => 50 + end +}}} + +Or, to paint a fifty pixel column on the right-side of the window: + +{{{ + #!ruby + Shoes.app do + background black, :width => 50, :right => 50 + end +}}} + +Since Backgrounds are normal elements as well, see also the start of the +[[Elements]] section for all of its other methods. + +=== to_pattern() » a Shoes::Pattern === + +Yanks out the color, gradient or image used to paint this background and places +it in a normal Shoes::Pattern object. You can then pass that object to other +backgrounds and borders. Reuse it as you like. + +== Border == + +A border is a color, gradient or image painted in a line around the edge of any +slot. Like the Background element in the last section, a Border is a kind of +Shoes::Pattern. !{:margin_left => 100}man-ele-border.png! + +The first, crucial thing to know about border is that all borders paint a line +around the '''inside''' of a slot, not the outside. So, if you have a slot +which is fifty pixels wide and you paint a five pixel border on it, that means +there is a fourty pixel wide area inside the slot which is surrounded by the +border. + +This also means that if you paint a Border on top of a [[Background]], the +edges of the background will be painted over by the border. + +Here is just such a slot: + +{{{ + #!ruby + Shoes.app do + stack :width => 50 do + border black, :strokewidth => 5 + para "=^.^=", :stroke => green + end + end +}}} + +If you want to paint a border around the outside of a slot, you'll need to wrap +that slot in another slot. Then, place the border in the outside slot. + +{{{ + #!ruby + Shoes.app do + stack :width => 60 do + border black, :strokewidth => 5 + stack :width => 50 do + para "=^.^=", :stroke => green + end + end + end +}}} + +In HTML and many other languages, the border is painted on the outside of the +box, thus increasing the overall width of the box. Shoes was designed with +consistency in mind, so that if you say that a box is fifty pixels wide, it +stays fifty pixels wide regardless of its borders or margins or anything else. + +Please also check out the [[Elements]] section for other methods used on borders. + +=== to_pattern() » a Shoes::Pattern === + +Creates a basic pattern object based on the color, gradient or image used to +paint this border. The pattern may then be re-used in new borders and +backgrounds. + +== Button == + +Buttons are, you know, push buttons. You click them and they do something. +Buttons are known to say "OK" or "Are you sure?" And, then, if you're sure, +you click the button. !{:margin_left => 100}man-ele-button.png! + +{{{ + #!ruby + Shoes.app do + button "OK!" + button "Are you sure?" + end +}}} + +The buttons in the example above don't do anything when you click them. In +order to get them to work, you've got to hook up a block to each button. + +{{{ + #!ruby + Shoes.app do + button "OK!" do + append { para "Well okay then." } + end + button "Are you sure?" do + append { para "Your confidence is inspiring." } + end + end +}}} + +So now we've got blocks for the buttons. Each block appends a new paragraph to +the page. The more you click, the more paragraphs get added. + +It doesn't go much deeper than that. A button is just a clickable phrase. + +Just to be pedantic, though, here's another way to write that last example. + +{{{ + #!ruby + Shoes.app do + @b1 = button "OK!" + @b1.click { para "Well okay then." } + @b2 = button "Are you sure?" + @b2.click { para "Your confidence is inspiring." } + end +}}} + +This looks dramatically different, but it does the same thing. The first +difference: rather than attaching the block directly to the button, the block +is attached later, through the `click` method. + +The second change isn't related to buttons at all. The `append` block was +dropped since Shoes allows you to add new elements directly to the slot. So we +can just call `para` directly. (This isn't the case with the `prepend`, +`before` or `after` methods.) + +Beside the methods below, buttons also inherit all of the methods that are +[[Common]]. + +=== click() { |self| ... } » self === + +When a button is clicked, its `click` block is called. The block is handed +`self`. Meaning: the button which was clicked. + +=== focus() » self === + +Moves focus to the button. The button will be highlighted and, if the user +hits Enter, the button will be clicked. + +== Check == + +Check boxes are clickable square boxes than can be either checked or unchecked. +A single checkbox usually asks a "yes" or "no" question. Sets of checkboxes +are also seen in to-do lists. !{:margin_left => 100}man-ele-check.png! + +Here's a sample checklist. + +{{{ + #!ruby + Shoes.app do + stack do + flow { check; para "Frances Johnson" } + flow { check; para "Ignatius J. Reilly" } + flow { check; para "Winston Niles Rumfoord" } + end + end +}}} + +You basically have two ways to use a check. You can attach a block to the +check and it'll get called when the check gets clicked. And/or you can just +use the `checked?` method to go back and see if a box has been checked or not. + +Okay, let's add to the above example. + +{{{ + #!ruby + Shoes.app do + @list = ['Frances Johnson', 'Ignatius J. Reilly', + 'Winston Niles Rumfoord'] + + stack do + @list.map! do |name| + flow { @c = check; para name } + [@c, name] + end + + button "What's been checked?" do + selected = @list.map { |c, name| name if c.checked? }.compact + alert("You selected: " + selected.join(', ')) + end + end + end +}}} + +So, when the button gets pressed, each of the checks gets asked for its status, +using the `checked?` method. + +Button methods are listed below, but also see the list of [[Common]] methods, +which all elements respond to. + +=== checked?() » true or false === + +Returns whether the box is checked or not. So, `true` means "yes, the box is checked!" + +=== checked = true or false === + +Marks or unmarks the check box. Using `checked = false`, for instance, +unchecks the box. + +=== click() { |self| ... } » self === + +When the check is clicked, its `click` block is called. The block is handed +`self`, which is the check object which was clicked. + +Clicks are sent for both checking and unchecking the box. + +=== focus() » self === + +Moves focus to the check. The check will be highlighted and, if the user hits +Enter, the check will be toggled between its checked and unchecked states. + +== EditBox == + +Edit boxes are wide, rectangular boxes for entering text. On the web, they +call these textareas. These are multi-line edit boxes for entering longer +descriptions. Essays, even! !{:margin_left => 100}man-ele-editbox.png! + +Without any other styling, edit boxes are sized 200 pixels by 108 pixels. You +can also use `:width` and `:height` styles to set specific sizes. + +{{{ + #!ruby + Shoes.app do + edit_box + edit_box :width => 100, :height => 100 + end +}}} + +Other controls (like [[Button]] and [[Check]]) have only click events, but both +[[EditLine]] and EditBox have a `change` event. The `change` block is called +every time someone types into or deletes from the box. + +{{{ + #!ruby + Shoes.app do + edit_box do |e| + @counter.text = e.text.size + end + @counter = strong("0") + para @counter, " characters" + end +}}} + +Notice that the example also uses the [[EditBox.text]] method inside the block. +That method gives you a string of all the characters typed into the box. + +More edit box methods are listed below, but also see the list of [[Common]] +methods, which all elements respond to. + +=== change() { |self| ... } » self === + +Each time a character is added to or removed from the edit box, its `change` +block is called. The block is given `self`, which is the edit box object which +has changed. + +=== focus() » self === + +Moves focus to the edit box. The edit box will be highlighted and the user will +be able to type into the edit box. + +=== text() » self === + +Return a string of characters which have been typed into the box. + +=== text = a string === + +Fills the edit box with the characters of `a string`. + +== EditLine == + +Edit lines are a slender, little box for entering text. While the EditBox is +multi-line, an edit line is just one. Line, that is. Horizontal, in fact. +!{:margin_left => 100}man-ele-editline.png! + +The unstyled edit line is 200 pixels wide and 28 pixels wide. Roughly. The +height may vary on some platforms. + +{{{ + #!ruby + Shoes.app do + stack do + edit_line + edit_line :width => 400 + end + end +}}} + +You can change the size by styling both the `:width` and the `:height`. +However, you generally only want to style the `:width`, as the height will be +sized to fit the font. (And, in current versions of Shoes, the font for edit +lines and edit boxes cannot be altered anyway.) + +If a block is given to an edit line, it receives `change` events. Check out the +[[EditBox]] page for an example of using a change block. In fact, the edit box +has all the same methods as an edit line. Also see the list of [[Common]] +methods, which all elements respond to. + +=== change() { |self| ... } » self === + +Each time a character is added to or removed from the edit line, its `change` +block is called. The block is given `self`, which is the edit line object which +has changed. + +=== focus() » self === + +Moves focus to the edit line. The edit line will be highlighted and the user +will be able to type into the edit line. + +=== text() » self === + +Return a string of characters which have been typed into the box. + +=== text = a string === + +Fills the edit line with the characters of `a string`. + +== Image == + +An image is a picture in PNG, JPEG or GIF format. Shoes can resize images or +flow them in with text. Images can be loaded from a file or directly off the +web. !{:margin_left => 100}man-ele-image.png! + +To create an image, use the `image` method in a slot: + +{{{ + #!ruby + Shoes.app do + para "Nice, nice, very nice. Busy, busy, busy." + image "static/shoes-manual-apps.gif" + end +}}} + +When you load any image into Shoes, it is cached in memory. This means that if +you load up many image elements from the same file, it'll only really load the +file once. + +You can use web URLs directly as well. + +{{{ + #!ruby + Shoes.app do + image "http://hacketyhack.heroku.com/images/logo.png" + end +}}} + +When an image is loaded from the web, it's cached on the hard drive as well as +in memory. This prevents a repeat download unless the image has changed. (In +case you're wondering: Shoes keeps track of modification times and etags just +like a browser would.) + +Shoes also loads remote images in the background using system threads. So, +using remote images will not block Ruby or any intense graphical displays you +may have going on. + +=== full_height() » a number === + +The full pixel height of the image. Normally, you can just use the +[[Common.height]] method to figure out how many pixels high the image is. But +if you've resized the image or styled it to be larger or something, then +`height` will return the scaled size. + +The `full_height` method gives you the height of image (in pixels) as it was +stored in the original file. + +=== full_width() » a number === + +The full pixel width of the image. See the [[Image.full_height]] method for an +explanation of why you might use this method rather than [[Common.width]]. + +=== path() » a string === + +The URL or file name of the image. + +=== path = a string === + +Swaps the image with a different one, loaded from a file or URL. + +== ListBox == + +List boxes (also called "combo boxes" or "drop-down boxes" or "select boxes" in +some places) are a list of options that drop down when you click on the box. +!{:margin_left => 100}man-ele-listbox.png! + +A list box gets its options from an array. An array (a list) of strings, +passed into the `:items` style. + +{{{ + #!ruby + Shoes.app do + para "Choose a fruit:" + list_box :items => ["Grapes", "Pears", "Apricots"] + end +}}} + +So, the basic size of a list box is about 200 pixels wide and 28 pixels high. +You can adjust this length using the `:width` style. + +{{{ + #!ruby + Shoes.app do + para "Choose a fruit:" + list_box :items => ["Grapes", "Pears", "Apricots"], + :width => 120, :choose => "Apricots" do |list| + @fruit.text = list.text + end + + @fruit = para "No fruit selected" + end +}}} + +Next to the `:width` style, the example uses another useful option. The +`:choose` option tells the list box which of the items should be highlighted +from the beginning. (There's also a [[ListBox.choose]] method for highlighting +an item after the box is created.) + +List boxes also have a [[ListBox.change]] event. In the last example, we've got +a block hooked up to the list box. Well, okay, see, that's a `change` block. +The block is called each time someone changes the selected item. + +Those are the basics. Might you also be persuaded to look at the [[Common]] +methods page, a complete list of the methods that all elements have? + +=== change() { |self| ... } » self === + +Whenever someone highlights a new option in the list box (by clicking on an +item, for instance,) its `change` block is called. The block is given `self`, +which is the list box object which has changed. + +=== choose(item: a string) » self === + +Selects the option in the list box that matches the string given by `item`. + +=== focus() » self === + +Moves focus to the list box. The list box will be highlighted and, if the user +hits the up and down arrow keys, other options in the list will be selected. + +=== items() » an array of strings === + +Returns the complete list of strings that the list box presently shows as its options. + +=== items = an array of strings === + +Replaces the list box's options with a new list of strings. + +=== text() » a string === + +A string containing whatever text is shown highlighted in the list box right +now. If nothing is selected, `nil` will be the reply. + +== Progress == + +Progress bars show you how far along you are in an activity. Usually, a +progress bar represents a percentage (from 0% to 100%.) Shoes thinks of +progress in terms of the decimal numbers 0.0 to 1.0. !{:margin_left => +100}man-ele-progress.png! + +A simple progress bar is 200 pixels wide, but you can use the `:width` style +(as with all Shoes elements) to lengthen it. + +{{{ + Shoes.app do + stack :margin => 0.1 do + title "Progress example" + @p = progress :width => 1.0 + + animate do |i| + @p.fraction = (i % 100) / 100.0 + end + end + end +}}} + +Take a look at the [[Common]] methods page for a list of methods found an all +elements, including progress bars. + +=== fraction() » a decimal number === + +Returns a decimal number from 0.0 to 1.0, indicating how far along the progress bar is. + +=== fraction = a decimal number === + +Sets the progress to a decimal number between 0.0 and 1.0. + +== Radio == + +Radio buttons are a group of clickable circles. Click a circle and it'll be +marked. Only one radio button can be marked at a time. (This is similar to the +ListBox, where only one option can be selected at a time.) !{:margin_left => +100}man-ele-radio.png! + +So, how do you decide when to use radio buttons and when to use list boxes? +Well, list boxes only show one highlighted item unless you click on the box and +the drop-down appears. But radio buttons are all shown, regardless of which is +marked. + +{{{ + #!ruby + Shoes.app do + para "Among these films, which do you prefer?\n" + radio; para strong("The Taste of Tea"), " by Katsuhito Ishii\n" + radio; para strong("Kin-Dza-Dza"), " by Georgi Danelia\n" + radio; para strong("Children of Heaven"), " by Majid Majidi\n" + end +}}} + +Only one of these three radios can be checked at a time, since they are grouped +together in the same slot (along with a bunch of `para`.) + +If we move them each into their own slot, the example breaks. + +{{{ + #!ruby + Shoes.app do + stack do + para "Among these films, which do you prefer?" + flow { radio; para "The Taste of Tea by Katsuhito Ishii" } + flow { radio; para "Kin-Dza-Dza by Georgi Danelia" } + flow { radio; para "Children of Heaven by Majid Majidi" } + end + end +}}} + +This can be fixed, though. You can group together radios from different slots, +you just have to give them all the same group name. + +Here, let's group all these radios in the `:films` group. + +{{{ + #!ruby + Shoes.app do + stack do + para "Among these films, which do you prefer?" + flow do + radio :films + para "The Taste of Tea by Katsuhito Ishii" + end + flow do + radio :films + para "Kin-Dza-Dza by Georgi Danelia" + end + flow do + radio :films + para "Children of Heaven by Majid Majidi" + end + end + end +}}} + +For more methods beyond those listed below, also look into the [[Common]] +methods page. Because you get those methods on every radio as well. + +=== checked?() » true or false === + +Returns whether the radio button is checked or not. So, `true` means "yes, it +is checked!" + +=== checked = true or false === + +Marks or unmarks the radio button. Using `checked = false`, for instance, +clears the radio. + +=== click() { |self| ... } » self === + +When the radio button is clicked, its `click` block is called. The block is +handed `self`, which is an object representing the radio which was clicked. + +Clicks are sent for both marking and unmarking the radio. + +=== focus() » self === + +Moves focus to the radio. The radio will be highlighted and, if the user hits +Enter, the radio will be toggled between its marked and unmarked states. + +== Shape == + +A shape is a path outline usually created by drawing methods like `oval` and +`rect`. !{:margin_left => 100}man-ele-shape.png! + +See the [[Common]] methods page. Shapes respond to all of those methods. + +== TextBlock == + +The TextBlock object represents a group of text organized as a single element. +A paragraph containing bolded text, for example. A caption containing links and +bolded text. (So, a `caption` is a TextBlock type. However, `link` and +`strong` are TextClass types.) !{:margin_left => 100}man-ele-textblock.png! + +All of the various types of TextBlock are found on the [[Element Element +Creation]] page. + + * [[Element.banner]], a 48 pixel font. + * [[Element.title]], a 34 pixel font. + * [[Element.subtitle]], a 26 pixel font. + * [[Element.tagline]], an 18 pixel font. + * [[Element.caption]], a 14 pixel font. + * [[Element.para]], a 12 pixel font. + * [[Element.inscription]], a 10 pixel font. + +=== contents() » an array of elements === + +Lists all of the strings and styled text objects inside this block. + +=== replace(a string) === + +Replaces the text of the entire block with the characters of `a string`. + +=== text() » a string === + +Return a string of all of the characters in this text box. This will strip off +any style or text classes and just return the actual characters, as if seen on +the screen. + +=== text = a string === + +Replaces the text of the entire block with the characters of `a string`. + +=== to_s() » a string === + +An alias for [[TextBlock.text]]. Returns a flattened string of all of this +TextBlock's contents. + +== Timers == + +Shoes contains three timer classes: the Animation class, the Every class and +the Timer class. Both Animations and Everies loop over and over after they +start. Timers happen once. A one-shot timer. + +Animations and Everies are basically the same thing. The difference is that +Animations usually happen many, many times per second. And Everies happen only +once every few seconds or rarely. + +=== start() » self === + +Both types of timers automatically start themselves, so there's no need to use +this normally. But if you [[Timers.stop]] a timer and would like to start it up +again, then by all means: use this! + +=== stop() » self === + +Pauses the animation or timer. In the case of a one-shot timer that's already +happened, it's already stopped and this method will have no effect. + +=== toggle() » self === + +If the animation or timer is stopped, it is started. Otherwise, if it is +already running, it is stopped. + +== Video == + +Shoes supports embedding of QuickTime, Flash video (FLV), DivX, Xvid and +various other popular video formats. This is all thanks to VideoLAN and ffmpeg, +two sensational open source libraries. Use the `video` method on a slot to +setup a Shoes::Video object. !{:margin_left => 100}man-ele-video.png! + +In addition to video formats, some audio formats are also supported, such as +MP3, WAV and Ogg Vorbis. + +Video support is optional in Shoes and some builds do not support video. For +example, video support is unavailable for PowerPC. When you download Shoes, the +build for your platform will be marked `novideo` in the filename if no video +support is available. + +=== hide() » self === + +Hides the video. If already playing, the video will continue to play. This just +turns off display of the video. One possible use of this method is to collapse +the video area when it is playing an audio file, such as an MP3. + +=== length() » a number === + +The full length of the video in milliseconds. Returns nil if the video is not +yet loaded. + +=== move(left, top) » self === + +Moves the video to specific coordinates, the (left, top) being the upper left +hand corner of the video. + +=== pause() » self === + +Pauses the video, if it is playing. + +=== playing?() » true of false === + +Returns true if the video is currently playing. Or, false if the video is +paused or stopped. + +=== play() » self === + +Starts playing the video, if it isn't already playing. If already playing, the +video is restarted from the beginning. + +=== position() » a decimal === + +The position of the video as a decimanl number (a Float) between the beginning +(0.0) and the end (1.0). For instance, a Float value of 0.5 indicates the +halfway point of the video. + +=== position = a decimal === + +Sets the position of the video using a Float value. To move the video to its +25% position: `@video.position = 0.25`. + +=== remove() » self === + +Removes the video from its slot. This will stop the video as well. + +=== show() » self === + +Reveals the video, if it has been hidden by the `hide()` method. + +=== stop() » self === + +Stops the video, if it is playing. + +=== time() » a number === + +The time position of the video in milliseconds. So, if the video is 10 seconds +into play, this method would return the number 10000. + +=== time = a number === + +Set the position of the video to a time in milliseconds. + +=== toggle() » self === + +Toggles the visibility of the video. If the video can be seen, then `hide` is +called. Otherwise, `show` is called. + += AndSoForth = + +A place for some other information. + +== Sample Apps == + +Have fun! + +{SAMPLES} + +== FAQ == + +Hope this helps: + + * You can join [[http://librelist.com/browser/shoes/ Shoes ML]] and feel free ask your questions. + * [[http://github.com/shoes/shoes/ Official Current Source Code]] is on GitHub. + * [[http://wiki.github.com/shoes/shoes/recentbuilds/ Recent Builds]] for your platform. diff --git a/static/manual-ja.txt b/static/manual-ja.txt new file mode 100644 index 0000000..e0a239a --- /dev/null +++ b/static/manual-ja.txt @@ -0,0 +1,2825 @@ += Hello! = + +Shoesは軽量なグラフィックツールキットです。これは単純で分かりやすいです。Shoesは簡単になるように生まれました。本当に、これは全くの初心者のために作られました。本当に簡単です。 + +このたった一行の取るに足りないShoesのプログラムを見てください: + +{{{ + #!ruby + Shoes.app { button("Click me!") { alert("Good job.") } } +}}} + +ShoesプログラムはRubyと呼ばれる言語で書かれています。ShoesがこのRubyコードの単純な行を渡されたとき、"Click me!"と中に書かれたボタンを持ったウィンドウを表示します。このボタンをクリックすると、メッセージがポップアップします。 + +Linuxでは、このように見えるでしょう: !{:margin_left => 100}man-shot1.png! + +多くのShoesのアプリケーションがグラフィカルなゲームやアートのプログラムである一方、テキストを配置したり編集したりすることも簡単にできます。 !{:margin_left => 40}shoes-manual-apps.gif! + +そして、理想的には、Shoesプログラムは世の中のいくつかの有名なプラットフォームで実行できるでしょう。マイクロソフトWindows、アップルのMac OS X、Linuxや多くの他のプラットフォームで。 + +^そして、Shoesのビルトインマニュアルへようこそ。このマニュアルはShoesのプログラムそのものです。^ + +== Introducing Shoes == + +OS XやWindowsではShoesはどのように見えるでしょうか?見栄えはいいですか?全体的に見苦しくて不格好ですか?みんなすぐに身悶えしたに違いないです!それは何をしようとしても、とても質が落ちたものに違いありません。 + +それでは、Shoesのインストールや実行について入る前に、何ができるのかの参考に、ちょっといくつかのスクリーンショットを確認します。 + +==== Mac OS X ==== + +ShoesはアップルのMac OS X Leopardで、同様にTigerでも動作します。ShoesはPowerPCマシンの同様にサポートしますが、そのプラットフォームではビデオ機能はサポートされません。 !man-look-tiger.png! + +これはTigerで実行している`simple-sphere.rb`サンプルです。アプリケーションは通常のOS Xウィンドウの枠の中で実行されていることに注意して下さい。 + +この球の全体は不鮮明な楕円形と影によって描かれています。Shoesでは、生き生きとした形状を描くことや、それらの形状に効果を適用することができます。 + +==== Windows ==== + +Shoesはすべてのバージョンの'''Microsoft Windows XP'''、 '''Windows Vista'''、 '''Windows 7'''で実行でき、他にも'''Windows 2000'''で互換性があります。 !man-look-vista.png! + +上記はWindows Vistaで`simple-clock.rb`サンプルが動作している図です。この例でも時計を作るために楕円と線が描かれており、これは一秒に何回かそれ自信が再描画するのので生き生きと描かれます。 + +アプリケーション上部のテキストが、現在の時刻を表示していることに注意してください。Shoesは、いくつかの色、太字、斜字、下線、そしてファイルからフォントをロードして語句を配置する機能を持っています。 + +==== Linux ==== + +これは'''Ubuntu Linux'''上で`simple-downloader.rb`サンプルが動作しているスクリーンショットです。!man-look-ubuntu.png! + +ボタンとプログレスバーに注意してください。これらの種類のコントロールはOS XとWindowsとは異なるように見えます。しかし、テキストとリンクは同じように見えるでしょう。 + +形状、テキスト、画像や動画はすべてのプラットフォームで同じように見えます。しかしながら、ネイティブコントロール(エディットラインやエディットボックスのような)はウィンドウテーマの見た目に一致します。Shoesはネイティブコントロールを、見た目は変化しますが、指定した大きさの範囲内で維持しようとします。 + +== Installing Shoes == + +はい、ではShoesのインストールを行います。あなたは次のような疑問を持っているでしょう:Rubyのインストールは必要ですか?なにも解凍しなくてもいいですか?どんなコマンドをタイプする必要がありますか? + +いや。Rubyを必要としません。WinZipを必要としません。なにもタイプしなくていいです。 + +Shoesを開始するには、多くのシステムではShoesのアイコンをクリックしてインストーラを実行するだけです。Shoesはすべてを組み込みで備えています。もっとも、まさしくそれに関して明確になるように、私たちはすべてのステップについて話をします。 + +==== Step 1: Shoesのインストール ==== + +[[http://shoes.heroku.com/ the site of Shoes]]へアクセスしてShoesのインストーラをダウンロードします。通常はホームページの上部の角にあるインストーラのひとつを手に入れます。 !man-builds.png! + +ここにインストーラの実行方法があります: + + * '''Mac OS X'''では、'''.dmg'''で終わっているファイルを手に入れます。このファイルをダブルクリックすると、'''Shoes'''アイコンと'''Applications'''フォルダと共にウィンドウが表示されます。矢印に従って'''Applications'''フォルダにShoesアイコンをドラッグします。 !man-intro-dmg.png! +* '''Windows'''では、'''.exe'''ファイルをダウンロードします。このファイルをダブルクリックして次の指示に従ってください。!man-intro-exe.png! +* '''Linux'''では、'''.run'''で終わっているファイルをダウンロードします。このファイルをダブルクリックするとShoesが起動します。(シェルスクリプトのようにプロンプトからこのファイルを実行することもできます。実際には、これは小さなシェルスクリプトです。) + +==== Step 2: 新しいテキストファイルの作成 ==== + +Shoesプログラムは'''.rb'''の拡張子で終わる、ただの単純なテキストファイルです。 + +空のテキストファイルを作成するいくつかの方法は: + + * '''Mac OS X'''では'''Applications'''フォルダに移動して'''TextEdit'''アプリケーションをダブルクリックします。空のエディタウィンドウが表示されます。そして'''Format'''メニューから'''Make Plain Text'''オプションを選択します。はい、準備ができました。!man-editor-osx.png! + * '''Windows'''では、スタートメニューへ行きます。'''All Programs'''、'''Accessories'''そして'''Notepad'''を選択します。. !man-editor-notepad.png! + * '''Linux'''では、多くのディストリビューションが'''gedit'''を備えています。それを実行してください。または、もしあなたのディストリビューションがKDEを基にしているのであれば'''kate'''を実行してください。 + +そして、空のウィンドウに次のようにタイプしてください: + +{{{ + Shoes.app do + background "#DFA" + para "Welcome to Shoes" + end +}}} + +`welcome.rb`としてデスクトップに保存してください。 + +==== Step 3: それを実行してください!Shoesへ行こう! ==== + +プログラムを実行するためには: + + * '''Mac OS X'''では、'''Applications'''へ再度行きます。今度は、そのフォルダの'''Shoes'''アイコンをダブルクリックします。そのドックの中に赤い靴のアイコンが現れます。'welcome.rb'をデスクトップから、そのドックアイコンへドラッグしてください。 + * '''Windows'''では、スタートメニューへから'''All Programs'''、'''Shoes'''そして'''Shoes'''へ行きます。ファイルの選択ボックスが表示されます。デスクトップに目を通して'welcome.rb'を選択します。'''OK'''をクリックしたら、後は自分でやってください。!man-run-xp.png! !man-run-vista.png! + * '''Linux'''では、ほとんど一回の手続きでだけでShoesを実行します。あなたはファイル選択ボックスを見るはずです。デスクトップに目を通して、`welcome.rb`を選択して'''OK'''を押してください。 + +まだ大したものではないですが、確かにそれはプログラムです!少なくとも、そのコツが分かったでしょう! + +==== Shoesで何を作りますか? ==== + +さて、ウィンドウアプリケーションを作成することができます。しかし、Shoesはウェブから影響を受けているので、アプリケーションは多くのウィジェットよりも、画像を使ったりテキストを配置する傾向があります。例えば、Shoesはタブコントロールやツールバーを備えていません。Shoesは''軽量な''ツールきっとだと言うことを覚えていますか? + +それでもShoesはボタンやエディットボックスのようなウィジェットを少しだけ持っています。そして、多くの(タブコントロールまたはツールバーのような)不足している要素は、画像でシミュレーションすることができます。 + +ShoesはCairoと呼ばれるとてもよくできた描画エンジンによって一部書かれており、それは形状や色彩を描くのに利用されています。このように、Shoesは、生き生きとしたグラフィックを描画するためにとてもいい言語である、NodeBoxとProcessingから影響を受けています。 + +== The Rules of Shoes == + +Shoesがどのように動作するのか推測するのはやめましょう。トリッキーな動作で悩むと思います。私はShoesの中心的な規則を要約しまいた。これらは、それにすべての働きをさせるためには知らなくてはならないものです。 + +これらはShoesの至る所に目にする一般的な規則です。Shoesは単純さと明解さという全体的な理念を持っていますが、いくつか勉強したり覚えたりする必要のあるポイントがあります。 + +==== Shoesのトリッキーなブロック ==== + +はい、これは極めて重要です。Shoesはブロックによってトリックをします。このトリックはすべてのものを読みやすくします。しかし、これは深い階層でブロックを利用することを難しくもします。 + +'''普通のRubyブロックを試しましょう:''' + +{{{ + ary = ['potion', 'swords', 'shields'] + ary.each do |item| + puts item + end +}}} + +Shoesでは、これらの種類のブロックは同じ働きをします。この上記のブロックは配列をループして各オブジェクトを`item`変数に格納します。この`item`変数はブロックが終わると消滅(スコープから出る)します。 + +考え方を守っているもう一つのことは、普通のRubyブロックの内部と`self`を同じままにしています。`each`の前に呼ばれるどんな`self`でも、それは`each`ブロック内部と同じです。 + +'''これらはどちらも大部分のShoesのブロックで正しいです。''' + +{{{ + Shoes.app do + stack do + para "First" + para "Second" + para "Third" + end + end +}}} + +ここでは二つのブロックがあります。一つ目は`Shoes.app`によるものです。この`app`ブロックは`self`を変更します。 + +もう一方のブロックは`stack`ブロックです。このブロックはselfを変更しません。 + +'''どんな理由があって`app`ブロックはselfを変更するのでしょうか?''' 最後の例を徹底的に詳しく説明することから始めましょう。 + +{{{ + Shoes.app do + self.stack do + self.para "First" + self.para "Second" + self.para "Third" + end + end +}}} + +上記の例におけるすべての`self`はアプリケーションオブジェクトです。Shoesは`app`ブロック内部でselfを変更するために、Rubyの`instance_eval`を利用します。そして、そのメソッドは`stack`を呼び出して`para`をアプリケーションへ送ります。 + +'''これはShoesアプリケーション全体でインスタンス変数が利用できる理由でもあります:''' + +{{{ + Shoes.app do + @s = stack do + @p1 = para "First" + @p2 = para "Second" + @p3 = para "Third" + end + end +}}} + +これらのインスタンス変数は、すべてアプリケーションオブジェクト内部で終了します。 + +'''新しいウィンドウを作成するときはいつでも、`self`も変更されます。'''そして、Shoes.appに加えて、これは[[Element.window]]と[[Element.dialog]]メソッドを意味します。 + +{{{ + Shoes.app :title => "MAIN" do + para self + button "Spawn" do + window :title => "CHILD" do + para self + end + end + end +}}} + +==== ブロックリダイレクション ==== + +もっとも、`stack`ブロックは別の話です。これは`self`を変えませんし、基本的に標準のブロックです。 + +'''しかしトリックがあります:'''`stack`を配置してブロックを与えたとき、アプリケーションオブジェクトはstackをメモリへ配置します。ブロックが終了するときstackは立ち去ります。そのため、アプリケーションのトップスロットから新しいstackまで、ブロック内部のすべての描画は'''リダイレクト'''されます。 + +そのため、まず、たとえ彼らが確かにアプリケーションオブジェクトへ渡したとしても、それらの3つの`para`は`stack`上に描画されます。 + +{{{ + Shoes.app do + stack do + para "First" + para "Second" + para "Third" + end + end +}}} + +少しトリッキーですよね?これについて知っていても噛みつかれるかもしれません。 + +それがあなたをつかまえる一つの方法は、`app`ブロック外のプログラム内のどこか他で、stackを編集しようとすることです。 + +例えばstackオブジェクトを使いまわすとしましょう。そして、そのオブジェクトを編集するクラスを持ちます。 + +{{{ + class Messenger + def initialize(stack) + @stack = stack + end + def add(msg) + @stack.append do + para msg + end + end + end +}}} + +アプリケーションが始まるときに、stackオブジェクトをMessengerクラスへ渡すと仮定します。そして、後で、メッセージが来るとき、`add`メソッドはそのstackにパラグラフを追加するのに用いられます。正しく動作するでしょうか? + +いや、それは動作しません。`para`メソッドが見つかりません。すでにアプリケーションオブジェクトはまわりにありません。そして、それは`para`メソッドによるものです。 + +幸いにも、それぞれのShoesオブジェクトはアプリケーションオブジェクトを再び開かせる`app`メソッドを持っているため、さらなる編集ができます。 + +{{{ + class Messenger + def initialize(stack) + @stack = stack + end + def add(msg) + @stack.app do + @stack.append do + para msg + end + end + end + end +}}} + +ご想像のとおり、その`app`オブジェクトは`self`をアプリケーションオブジェクトに変更します。 + +ルールは次のようになります: + +1. '''"app"という名前か新しいウィンドウを作成するメソッドはアプリケーションオブジェクトの`self`を変更します。'''[[BR]](これは、[[Element.window]] と[[Element.dialog]]同様に、Shoes.appとSlot.appの両方にとって正しいです。)[[BR]]2. '''stackへ加えられるブロックは、フローや(追加などの)どんな操作メソッドでもselfを変更しません。その代わりに、彼らはスロットをアプリケーションの編集stackにポップします。''' + +==== 固定された高さに注意 ==== + +列でウィンドウを区切るように、スロットの固定された幅は重要です。 + +{{{ + Shoes.app do + flow do + stack :width => 200 do + caption "Column one" + para "is 200 pixels wide" + end + stack :width => -200 do + caption "Column two" + para "is 100% minus 200 pixels wide" + end + end + end +}}} + +スロットの固定された高さは、より一般的ではありません。通常は、テキストや画像がウィンドウの下へできるだけ流れることを望みます。高さは通常は自然に決定します。 + +ここで重要なことは、固定された高さが実際はスロットに違うように振る舞わせることです。確かに最後にはスロットは完全に切り離なされて、'''入れ子のウィンドウ'''になります。新しいレイヤーはオペレーティングシステムによってスロットを一定の正方形に保つために作成されます。 + +通常のスロットと入れ子ウィンドウのスロットとの違いは、後者はスクロールバーを持てることです。 + +{{{ + Shoes.app do + stack :width => 200, :height => 200, :scroll => true do + background "#DFA" + 100.times do |i| + para "Paragraph No. #{i}" + end + end + end +}}} + +これらの入れ子ウィンドウはより多くのメモリを必要とします。彼らはアプリケーションにもう少し負担をかけます。もしあなたが、固定された高さのたくさんのスロットで遅さを経験しているなら、違うアプローチを試してください。 + +==== 画像と形状のブロック ==== + +多くの初心者が形状でウィンドウを散らかし始めます。すべての長方形や楕円形をスロットへ投げ入れるのは確かに簡単です。 + +'''しかしながら、Shoesはそれらすべての形状のためにオブジェクトを生成することを覚えておいて下さい!。''' + +{{{ + Shoes.app do + fill black(0.1) + 100.times do |i| + oval i, i, i * 2 + end + end +}}} + +この例では、100個の楕円形オブジェクトが生成されます。これは悪すぎるわけではありません。しかし、一つの形状の中にこれらを作成するのなら、これはより軽量になるでしょう。 + +{{{ + Shoes.app do + fill black(0.1) + shape do + 100.times do |i| + oval i, i, i * 2 + end + end + end +}}} + +ああ、待ってください。この楕円形は今回は満たされません。なぜなら、この形状たちは一つの大きな形状に結合されたからです。そして、このケースではShoesはどこを満たすべきか、分かりません。 + +そして、アウトラインを厳密に扱うとき、通常は一つの形状に結合することを望みます。 + +別のオプションでは、これらすべての楕円形を一つの画像に結合します。 + +{{{ + Shoes.app do + fill black(0.1) + image 300, 300 do + 100.times do |i| + oval i, i, i * 2 + end + end + end +}}} + +そうしよう!その楕円形はすべて一つの300 x 300の画像に結合されます。この場合では、その画像をメモリに保管するのは、おそらく100個の楕円形を持つよりはるかに大きくなるかもしれません。しかし、何千もの形状を扱う場合には、イメージブロックはより安っぽくなる可能性があります。 + +ポイントは以下の通りです:画像やブロックへ形状をグループ化することは簡単ですので、もし速度を得ようとするのなら、それを試してください。形状ブロックは特にメモリと速度を節約させるでしょう。 + +==== どこでもUTF-8 ==== + +Ruby自体はUnicodeを意識しません。そして、UTF-8は一種のUnicodeです。(UTF-8の完全な説明は[[http://en.wikipedia.org/wiki/UTF-8 Wikipedia]]を見てください。) + +しかしながら、UTF-8はWEBで一般的です。そして、多くの異なったプラットホームがそれをサポートします。そこで、Shoesがしなくてはならない変換の量を減らすために、Shoesはすべての文字列がUTF-8フォーマットであることを期待します。 + +すばらしいことに、ShoesでUTF-8を使えば無数の言語(ロシア語、日本語、スペイン語、英語)を表示ことができます。テキストエディタでUTF-8を使用することだけを確認してください! + +実例を示します: + +{{{ + Shoes.app do + stack :margin => 10 do + @edit = edit_box :width => 1.0 do + @para.text = @edit.text + end + @para = para "" + end + end +}}} + +このアプリケーションは何でもコピーして編集ボックスに貼り付けて、Shoesパラグラフで表示することができます。外国語(ギリシャ語か日本語のような)のテキストをこのボックスにコピーして、どのように表示されるかを見ることができます。 + +これは、その編集ボックスがUTF-8の文字を返すことを確かめるのにいいテストです。そして、そのパラグラフはどんなUTF-8の文字でも設定することができます。 + +'''重要事項:'''もしいくつかのUTF-8の文字が表示されないなら、パラグラフのフォントを変更する必要があります。これは特にOS Xで一般的です。 + +そして、OS Xでのおすすめの日本語フォントは'''AppleGothic'''です。Windowsでは'''MS UI Gothic'''です。 + +{{{ + Shoes.app do + para "てすと (te-su-to)", :font => case RUBY_PLATFORM + when /mingw/; "MS UI Gothic" + when /darwin/; "AppleGothic, Arial" + else "Arial" + end + end +}}} + +さらに、Shoesで文字列を扱う場合もUTF-8の文字列を必要とします。編集ボックス、編集ライン、リストボックス、ウィンドウタイトルやテキストブロックはすべてUTF-8をとります。間違った文字の入った文字列をあたえた場合は、コンソールにエラーが表示されます。 + +==== メインアプリケーションとRequire ==== + +'''注意:''' このルールはRaisinsのためのものです。PolicemanではTOPLEVEL_BINDINGを使っているので、最初の例では `main` (Rubyトップレベルオブジェクト)が表示されます。`Shoes.app`ブロックの外側では、`Para`ではなく`Shoes::Para`と記述する必要がありますが。 + + +それぞれのShoesアプリケーションは、それ自体を作ることができる小さな部屋を与えられます。クラスを作成したり変数を設定できますが、それらは他のShoesプログラムから見ることはできません。それぞれのプログラムはそれ自身の匿名クラス内で実行されます。 + +{{{ + main = self + Shoes.app do + para main.to_s + end +}}} + +この匿名クラスは`(shoes)`と呼ばれ、それは空の無名クラスです。`Shoes`モジュールは(`include Shoes`を利用して)このクラスにミックスインされているため、パラグラフクラスを参照しているときに`Para`や`Shoes::Para`を利用することができます。 + +このアプローチの長所は: + + * Shoesアプリケーションはローカル変数を共有できません。 + * メインアプリケーションコードに作成されるクラスは一時的です。 + * Shoesモジュールは、Ruby自身のトップレベル環境ではなく、匿名クラスにミックスインされることができます、 + * ガベージコレクションが一度完了すれば、アプリケーションを完全にきれいにできます。 + +二つ目の部分は特に重要なので忘れないこと。 + +{{{ + class Storage; end + + Shoes.app do + para Storage.new + end +}}} + +アプリケーションが完了すれば`Storage`クラスは消えます。ほかのアプリケーションはStorageクラスを利用できません。そして、それは`require`を利用してロードされるファイルから手に入れることはできません。 + +もっとも、`require`するときそのコードは近くにいます。それはRubyのトップレベル環境に保持されます。 + +そして、この規則は:'''アプリケーションのコードに一時的なクラスを保持し、requireに永続的なクラスを保持しなさい'''です。 + += Shoes = + +Shoesはウィンドウや、それらウィンドウ内部の要素を描くことがすべてです。今はウィンドウ自体に焦点を当てましょう。他のセクションの[[Slots]]や[[Elements]]がウィンドウ内部に関してのすべてを対象としています。 + +ここでは、このマニュアルはより辞書のように読んでください。それぞれのページのほとんどは、利用可能なメソッドの一覧であり、各トピックを対象としています。この考えは、すべてに関してとても詳細かつ明確であることです。 + +そして、このマニュアルの難しさにぶつかって、始めることについてまだ分からないなら、おそらくこのマニュアルの[[Hello! beginning]]に戻るべきです。 +または、ウェブ上の初心者のリーフレットである[[http://github.com/shoes/shoes/downloads Nobody Knows Shoes]]を試してください。 + +==== 方法の見つけ方 ==== + +このセクションは以下を対象とします: + + * [[Built-in Built-in methods]] - Shoesプログラムのどこでも利用できる一般的なメソッド。 + * [[App The App window]] - Shoesのすべてのメインウィンドウに添付されたメソッド。 + * [[Styles The Styles Master List]] - Shoesのすべてのスタイルの完全な一覧。 + * [[Classes The Classes list]] - Shoesのクラスやサブクラスについて表示している表。 + * [[Colors The Colors list]] - すべてのビルトインカラーと[[Built-in.rgb]]におけるそれぞれの数の表。 + +ページをよく見ても見つからないものがあれば、[[Search]]ページを試してください。それは問題をさける手っ取り早い方法です。 + +この一般的なリファレンスのあとに、他の2つの特別なセクションがあります: + + * [[Slots]] - [[Element.stack]]と[[Element.flow]]を対象とする、2つの種類のスロット。 + * [[Elements]] - すべてのボタン、形状、画像などのためのドキュメント。 + +ここに[[Element Element Creation]]ページ(追加できるすべてのエレメントの一覧)と[[Common Common Methods]] ページ(すべてのスロットやエレメントにあるメソッドの一覧)の2つのとても大切なページがあります。 + +== Built-in Methods == + +これらのメソッドはShoesのプログラムを通してどこでも利用できます。 + +これらすべてのコマンドは、あなたがドットを彼らに付与しない点が珍しいです。 +'''このマニュアルのほかのすべてのメソッドはオブジェクトにドットを付与すべきです。''' +しかし、これらのビルトインメソッド(カーネルメソッドとも呼ばれている)はドットがないことを意味します。 + +一般的なものとして`alert`があります: + +{{{ + #!ruby + alert "No dots in sight" +}}} + +これと、カーネルメソッドはなくArrayとStringに対してだけ利用可能な`reverse`メソッドを比較してください: + +{{{ + #!ruby + "Plaster of Paris".reverse + #=> "siraP fo retsalP" + [:dogs, :cows, :snakes].reverse + #=> [:snakes, :cows, :dogs] +}}} + +描画やボタンを作成したりするための多くのShoesメソッドはスロットへ付与されます。より詳しい情報については[[Slots]]のセクションを見てください。 + +==== ビルトイン定数 ==== + +Shoesにはいくつかのビルトイン定数があり、それはどんなバージョンのShoesが実行されているかを判別することを証明するのに利用できるかもしれません + +'''Shoes::RELEASE_NAME''' Shoesリリース名の文字列定数です。Curiousから始まって、すべてのShoesリリースは名付けられます。 + +'''Shoes::RELEASE_ID''' Shoesリリース表す数字を含みます。そして、例えばCuriousはナンバー1であり、それは初めての公式リリースです。 + +'''Shoes::REVISION''' は、そのビルドのSubversionのリビジョン番号です。 + +'''Shoes::FONTS''' は、アプリケーションで利用できるフォントの完全な一覧です。この一覧は[[Built-in.font]]メソッドによってロードされたすべてのフォントを含みます。 + +=== alert(message: a string) » nil === + +短いメッセージを含むウィンドウをポップアップします。 + +{{{ + #!ruby + alert("I'm afraid I must interject!") +}}} + +alertは信じられないほど煩わしいので控えめに利用してください!プログラムをデバッグする手助けのメッセージを表示するためにalertを利用するなら、[[Built-in.debug]]または[[Built-in.info]]メソッドを調べてみてください。 + +=== ask(message: a string) » a string === + +ウィンドウをポップアップして質問をします。例えば、あなたは誰かに名前を尋ねたいかもしれません。 + +{{{ + #!ruby + name = ask("Please, enter your name:") +}}} + +上記のスクリプトを実行するとき、コンピュータを利用している人は、名前を入力するための空のボックスを持つウィンドウを見るでしょう。そして、その名前は`name`変数に保存されます。 + +=== ask_color(title: a string) » Shoes::Color === + +カラーピッカーウィンドウをポップアップします。このプログラムは色が選ばれるのを待ち、そしてあなたに色オブジェクトを与えます。いくつかの方法でこの色を利用するために`Color`ヘルプを見てください。 + +{{{ + #!ruby + backcolor = ask_color("Pick a background") + Shoes.app do + background backcolor + end +}}} + +=== ask_open_file() » a string === + +"ファイルを開く。。。"ウィンドウをポップアップします。これは標準のウィンドウであり、すべてのフォルダを表示して開くファイルを選択させます。そしてファイルの名前を返します。 + +{{{ + #!ruby + filename = ask_open_file + Shoes.app do + para File.read(filename) + end +}}} + +=== ask_save_file() » a string === + +これは先ほど述べた`ask_open_file`と似ており、"ファイルを保存する。。。"ウィンドウをポップアップします。 + +{{{ + #!ruby + save_as = ask_save_file +}}} + +=== ask_open_folder() » a string === + +"フォルダを開く。。。"ウィンドウをポップアップします。これは、すべてのフォルダを表示し、開くフォルダを選択させる標準のウィンドウです。これはあなたにフォルダの名前を渡します。 + +{{{ + #!ruby + folder = ask_open_folder + Shoes.app do + para Dir.entries(folder) + end +}}} + +=== ask_save_folder() » a string === + +これは先ほど述べた`ask_open_folder`と似ており、"フォルダを保存する。。。"ウィンドウをポップアップします。OS X上では、現在このメソッドは`ask_open_folder`のエイリアスのようになっています。 + +{{{ + #!ruby + save_to = ask_save_folder +}}} + + +=== confirm(question: a string) » true or false === + +yes-または-noの質問をポップアップします。コンピュータの前の人が'''yes'''をクリックするなら、返される`true`を受け取ります。そうでは無いなら、返される`false`を受け取ります。 + +{{{ + #!ruby + if confirm("Draw a circle?") + Shoes.app{ oval :top => 0, :left => 0, :radius => 50 } + end +}}} + +=== debug(message: a string) » nil === + +Shoesコンソールへデバッグメッセージを送ります。 +どんなShoesウィンドウ上でも、`Alt-/`(または、OS X上では`⌘-/`)を押すことによって、Shoesコンソールを立ち上げることができます。 + +{{{ + #!ruby + debug("Running Shoes on " + RUBY_PLATFORM) +}}} + +[[Built-in.error]]、[[Built-in.warn]]と[[Built-in.info]]メソッドも確認してください。 + +=== error(message: a string) » nil === + +Shoesコンソールへエラーメッセージ送ります。このメソッドはエラーをログするためだけに利用すべきです。自分ためのメッセージをログするには[[Built-in.debug]]メソッドを試してください。 + +おお、そして、文字列よりも、直接このメソッドに例外を手渡すべきです。そしてそれは適切にフォーマットされるでしょう。 + +=== exit() === + +プログラムを止めます。突然に終了したいときはいつでも、これを呼んでください。 + +=== font(message: a string) » an array of font family names === + +ファイルからTrueType(または他の種類のフォント)をロードします。TrueTypeはすべてのプラットフォームでサポートされるとはいえ、あなたのプラットフォームは他の種類のフォントをサポートするかもしれません。Shoesはこの動作に、それぞれのオペレーティングシステムのビルトインフォントシステムを利用します。 + +ここにどのプラットフォームで何のフォントが動作するかの目安があります。 + + * Bitmap fonts (.bdf, .pcf, .snf) - Linux + * Font resource (.fon) - Windows + * Windows bitmap font file (.fnt) - Linux, Windows + * PostScript OpenType font (.otf) - Mac OS X, Linux, Windows + * Type1 multiple master (.mmm) - Windows + * Type1 font bits (.pfb) - Linux, Windows + * Type1 font metrics (.pfm) - Linux, Windows + * TrueType font (.ttf) - Mac OS X, Linux, Windows + * TrueType collection (.ttc) - Mac OS X, Linux, Windows + +フォントが適切にロードされたなら、ファイルに見つかったフォントの名前の配列を取り戻すでしょう。そうではなく、ファイルにはフォントが見つからないなら`nil`が返されます。 + +また興味深いことに:`Shoes::FONTS`定数はこのプラットフォームで利用可能なフォントの完全な一覧です。`include?`を利用していくつかのフォントをチェックできます。 + +{{{ + if Shoes::FONTS.include? "Helvetica" + alert "Helvetica is available on this system." + else + alert "You do not have the Helvetica font." + end +}}} + +もしフォントを表示することに問題があるなら、それを利用する前に、アプリケーションがフォントをロードすることを確認してください。特にOS Xでは、もしフォントがロードされる前に利用されたなら、フォントキャッシュはロードされたフォントを無視する傾向があります。 + +=== gradient(color1, color2) » Shoes::Pattern === + +二つの色から直線勾配を作ります。それぞれの色に、色を描画するためにShoes::Colorオブジェクトか文字列を渡します。 + +=== gray(the numbers: darkness, alpha) » Shoes::Color === + +暗さのレベルや、任意的にはアルファレベルからグレースケールカラーを作成します。 + +{{{ + black = gray(0.0) + white = gray(1.0) +}}} + +=== info(message: a string) » nil === + +Shoesコンソールでユーザへの情報を含むメッセージを記録します。そして、そのデバッグメッセージはプログラムで何が発生したのか見つけることを助けるようにデザインされており、`info`メッセージはプログラムについてユーザに追加の情報を教えます。 + +{{{ + #!ruby + + info("You just ran the info example on Shoes #{Shoes::RELEASE_NAME}.") +}}} + +例えば、Shyファイルをロードすればいつでも、ShoesはコンソールにShyの著者とバージョンの情報を含むメッセージを印字します。 + +=== rgb(a series of numbers: red, green, blue, alpha) » Shoes::Color === + +赤、緑、青の構成要素から色を作成します。アルファレベル(透明度を示す)は任意に加えることができます。 + +整数を渡すときは、0から255までの値を利用してください。 + +{{{ + blueviolet = rgb(138, 43, 226) + darkgreen = rgb(0, 100, 0) +}}} + +または、0.0から1.0までの10進数を利用してください。 + +{{{ + blueviolet = rgb(0.54, 0.17, 0.89) + darkgreen = rgb(0, 0.4, 0) +}}} + +このメソッドは`Shoes.rgb`と呼ばれるかもしれません。 + +=== warn(message: a string) » nil === + +ユーザのために警告を記録します。警告は壊滅的なエラー(それは[[Built-in.error]]を見てください。)ではありません。これは、プログラムが将来変化したり、プログラムの一部が信頼できなくなるなどの通知です。 + +警告やエラーを見るためには、`Alt-/`(OS Xの場合は`⌘-/`)によりShoesコンソールを開いてください。 + +== The App Object == + +アプリケーションはURLでコードを実行する一つのウィンドウです。URLを切り替えるとき、新しいアプリケーションオブジェクトが作成され、スタック、フローや他の要素で満たされます。 + +アプリケーションはウィンドウ自体です。それは閉じられるか、クリアされるか、新しい要素で満たされるかもしれません。!{:margin_left => 100}man-app.png! + +スロット/ボックスの用語では、アプリケーション自体がフローです。詳しくは''Slots''セクションを見てください、しかし、これはどんな要素も直接フローのトップレベルに置かれることを単に意味します。 + +=== Shoes.app(styles) { ... } » Shoes::App === + +Shoesのアプリケーションウィンドウを開始します。これはShoesプログラムを作るための出発地点です。ブロックの内部では、ウィンドウを様々なShoesの要素(ボタン、アートワーク、その他)で満たし、そしてブロックの外では、ウィンドウがどれぐらい大きいのかを説明するために`styles`を利用します。おそらくアプリケーションの名前や、それがリサイズ可能かどうかについてもです。 + +{{{ + #!ruby + Shoes.app(:title => "White Circle", + :width => 200, :height => 200, :resizable => false) { + background black + fill white + oval :top => 20, :left => 20, :radius => 160 + } +}}} + +上記のケースでは、小さなウィンドウを作成します。200×200ピクセルです。それはリサイズ不可能です。そして、そのウィンドウには黒い背景と白い輪の2つの要素があります。 + +いったんアプリケーションが作成されれば、それは[[App.Shoes.APPS]]の一覧に追加されます。もしあなたがより多くのウィンドウを生成したいなら、[[Element.window]]メソッドや[[Element.dialog]]メソッドを見てください。 + +=== Shoes.APPS() » An array of Shoes::App objects === + +現在開いているすべてのShoesアプリケーションの完全な一覧を作成します。いったんアプリケーションが閉じられると、その一覧から取り除かれます。そう、Shoesでは一度に多くの実行できます。それはとても元気付けられます。 + +=== clipboard() » a string === + +システムのクリップボードのすべてのテキストを含む文字列を返します。これはコンピュータ上のどのプログラムからでもカットアンドペーストできるグローバルクリップボードです。 + +=== clipboard = a string === + +システムクリップボードに`a string`のテキストを保存します。 + +=== close() === + +アプリケーションのウィンドウを閉じます。複数のウィンドウを開いていて、すべてのアプリケーションを閉じたいなら、ビルトインメソッドの`exit`を利用してください。 + +=== download(url: a string, styles) === + +ダウンロードのスレッド(あなたがJavaScriptに詳しいのなら、およそXMLHttpRequestのようなものです)を開始します。このメソッドは、すぐに戻り値を返してバックグラウンドでダウンロードを開始します。また、それぞれのダウンロードスレッドが`start`、`progress`や`finish`イベントを開始します。 +downloadにファイルを送ることや、(`finish`イベントの中で)文字列を取り戻すことができます。 + +downloadにブロックを付けると、それは`finish`イベントとして呼ばれます。 + +download + +{{{ + #!ruby + Shoes.app do + stack do + title "Searching Google", :size => 16 + @status = para "One moment..." + + # Search Google for 'shoes' and print the HTTP headers + download "http://www.google.com/search?q=shoes" do |goog| + @status.text = "Headers: " + goog.response.headers.inspect + end + end + end +}}} + +そして、ダウンロードしたデータを利用したいなら`goog.response.body`を利用することにより行います。この例は本当に`download`の最も簡単な形です:いくつかのウェブデータをメモリに取ってきて、それを一度ハンドリングしています。 + +`download`のもう一つのサンプルはいくつかのウェブデータを、`:save`スタイルを利用してファイルに保存します。 + +{{{ + #!ruby + Shoes.app do + stack do + title "Downloading Google image", :size => 16 + @status = para "One moment..." + + download "http://www.google.com/logos/nasa50th.gif", + :save => "nasa50th.gif" do + @status.text = "Okay, is downloaded." + end + end + end +}}} + +このケースでも、ダウンロードファイルのヘッダを取得することができますが、メモリにそのデータが保存されていないため`response.body`は`nil`になります。ダウンロードしたものを得るためにはそのファイルを開く必要があります。 + +特定のヘッダかアクションをウェブサーバへ送る必要があるのならば、HTTPリクエストをカスタマイズするために`:method`、`:headers`や`:body`スタイルを利用することができます。(そして、それら以上の変更の必要があるのなら、いつでもRubyのOpenURIクラスを破壊することができます。) + +{{{ + #!ruby + Shoes.app do + stack do + title "POSTing to Google", :size => 16 + @status = para "One moment..." + + download "http://www.stevex.net/dump.php", + :method => "POST", :body => "v=1.0&q=shoes" do |dump| + require 'hpricot' + @status.text = Hpricot(dump.response.body).inner_text + end + end + end +}}} + +上記の例から、ShoesはHTMLを解析するHpricotなライブラリを含んでいることが分かります。 + +=== location() » a string === + +現在のアプリケーションのURLを含む文字列を取得します。 + +=== mouse() » an array of numbers: button, left, top === + +どちらのボタンが押されたのかと共に、マウスカーソルの位置を特定します。 + +{{{ + #!ruby + Shoes.app do + @p = para + animate do + button, left, top = self.mouse + @p.replace "mouse: #{button}, #{left}, #{top}" + end + end +}}} + +=== owner() » Shoes::App === + +このアプリケーションを開始したアプリケーションを取得します。多くの場合、これは`nil`でしょう。しかし[[Element.window]]メソッドを利用してアプリケーションが開始されたなら、その所有者は`window`と呼ばれるアプリケーションでしょう。 + +=== started?() » true or false === + +ウィンドウはすべて構築され、表示されましたか?これは完全に構築される前に、ウィンドウを利用しようとするスレッド化されたコードのために役に立ちます。 +(また、ウィンドウが開くときに実行される`start`イベントも見てください。) + +=== visit(url: a string) === + +異なるShoesのURLを見るために、ロケーションを変更します。 + +(http://google.comのような)絶対パスのURLは悪くないですが、ShoesはShoesアプリケーションがそのアドレスに存在することを期待するでしょう。(そのため、google.comはHTMLアプリケーションとしては動作しません。) + +== The Styles Master List == + +外観を変更したいですか?Shoesにおいてはスタイルが要素の表示方法を変更するために利用されます。場合によっては、要素のすべてのクラスのスタイルでさえ設定できます。(すべての段落に特定のフォントを与えるように) + +スタイルは簡単にspotできます。通常は要素が生成されるときに現れます。 + +{{{ + Shoes.app :title => "A Styling Sample" do + para "Red with an underline", :stroke => red, :underline => "single" + end +}}} + +このappには`:title`スタイルが設定されています。そしてこのappの内部の段落には、赤い`:stroke`スタイルと`:underline`スタイルが設定されます。 + +このスタイルのハッシュは、どんな要素やスロットも利用できる[[Common.style]]メソッドを利用して変更できます。 + +{{{ + Shoes.app :title => "A Styling Sample" do + @text = para "Red with an underline" + @text.style(:stroke => red, :underline => "single") + end +}}} + +多くのスタイルもメソッドとして呼び出すことで設定することができます。(メソッドを見つけるために手動での検索を行うでしょう。) + +{{{ + Shoes.app :title => "A Styling Sample" do + @text = para "Red with an underline" + @text.stroke = red + @text.underline = "single" + end +}}} + +どんなスタイルでも分かるようにすべてのマニュアルを苦労して読ませるよりも、この役に立つページはShoesのあらゆるスタイルを急いで駆け抜けて、どこでスタイルが利用されるかについて示唆します。 + +=== :align » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +テキストの整列です。これは次のどれかです: + + * 'left': 左へテキストを整列します。 + * 'center': 中央へテキストを整列します。 + * 'right': 右へテキストを整列します。 + +=== :angle » a number === + +''background, border, gradient''で利用できます。 + +グラデーションに摘要する角度です。通常はグラデーションの色の効果は上から下です。`:angle`を90に設定するなら反時計回りに90度回転し、グラデーションは左から右になるでしょう。 + +=== :attach » a slot or element === + +''flow, stack''で利用できます。 + +他のスロットや要素と比較してスロットをピンで止めます。ウィンドウの左上の角からスロットを配置するために`:attach => Window`と書く人もいるかもしれません。 +これについてもう少し取り上げると、`:top => 10, :left => 10, :attach => Window`のスタイルはスロットをウインドウの座標の(10, 10)に配置します。 + +動く要素にスロットがアタッチされた場合は、そのスロットはそれとともに動きます。アタッチメントが`nil`にリセットされるなら、通常はそのスロットはそれを取り囲む他のオブジェクトとともに流れます。 + +=== :autoplay » true or false === + +''video''で利用できます。 + +ビデオは現れた後で再生を開始すべきですか?`true`を設定すると、ビデオはユーザに尋ねること無く開始するでしょう。 + +=== :bottom » a number === + +''すべてのスロットと要素''で利用できます。 + +要素の下の端の座標にピクセルを設定します。その端はコンテナの下の端に対して配置されます。そのため、`:bottom => 0`は、スロットの下の端とその下の端が接するように要素を配置するでしょう。 + +=== :cap » :curve or :rect or :project === + +''arc, arrow, border, flow, image, mask, rect, star, shape, stack''で利用できます。 + +線の終点の形状を曲がったもの(curved)か角張ったもの(square)に設定します。追加の説明は[[Art.cap]]メソッドを見てください。 + +=== :center » true or false === + +''arc, image, oval, rect, shape''で利用できます。 + +`:top`と`:left`の座標が形状の中心を意味するかどうか示します。`true`を設定すると、[[Art.transform]]メソッドに`:center`を設定したのと似ています。 + +=== :change » a proc === + +''edit_box, edit_line, list_box''で利用できます。 + +`change`イベントハンドラはスタイルに保存されます。例として、edit_boxの[[EditBox.change]]メソッドを見てください。 + +=== :checked » true or false === + +''check, radio''で利用できます。 + +チェックボックスまたはラジオボタンがクリックされましたか?`true`が設定されるなら、そのボックスはチェックされます。[[Check.checked=]]メソッドも見てください。 + +=== :choose » a string === + +''list_box''で利用できます。 + +リスト内の現在選択されたアイテムを設定します。追加の情報は[[ListBox.choose]]にあります。 + +=== :click » a proc === + +''arc, arrow, banner, button, caption, check, flow, image, inscription, line, link, mask, oval, para, radio, rect, shape, stack, star, subtitle, tagline, title''で利用できます。 + +`click`イベントハンドラはスタイルに保存されます。解説は[[Events.click]]メソッドを見てください。 + +=== :curve » a number === + +''background, border, rect''で利用できます。 + +長方形の要素のそれぞれの曲がった角の半径です。例として、6を設定した場合、長方形の角は6ピクセルの半径のカーブを与えられます。 + +=== :displace_left » a number === + +''すべてのスロットと要素''で利用できます。 + +形状、テキストブロックまたはその他のどんな種類のオブジェクトでも左か右に置き換えます。正数は与えられた数のピクセルによって右へ置き換え、負数は左へ置き換えます。オブジェクトを置き換えることはページの実際のレイアウトに影響を与えません。この振る舞いに少し驚くかもしれないので、このスタイルを利用する前に、[[Position.displace]]のドキュメントを読むようにしてください。 + +=== :displace_top » a number === + +''すべてのスロットと要素''で利用できます。 + +形状、テキストブロックまたはその他のどんな種類のオブジェクトでも上か下に置き換えます。正数は与えられた数のピクセルによって下へ置き換え、負数は上へ置き換えます。オブジェクトを置き換えることはページの実際のレイアウトやオブジェクトの本当の座標に影響を与えません。この振る舞いに少し驚くかもしれないので、[[Position.displace]]のドキュメントを読んでください。 + +=== :emphasis » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +強調によってテキストを整えます。(一般的にはイタリック体にされます。) + +このスタイルは3つの設定ができます: + + * "normal" - 直立のフォント。 + * "oblique" - ローマン体の傾いたフォント。 + * "italic" - イタリック体の傾いたフォント。 + +=== :family » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +与えられたフォントファミリーでテキストを整えます。文字列はフォントファミリー名かカンマで区切られたフォントファミリーの一覧を含むべきです。 + +=== :fill » a hex code, a Shoes::Color or a range of either === + +''arc, arrow, background, banner, caption, code, del, em, flow, image, ins, inscription, line, link, mask, oval, para, rect, shape, span, stack, star, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +背景のペンの色です。形状では、これは形状の内側を塗りつぶすペンキの色です。テキストなどでは、この色で背景が塗られます。(まるで蛍光ペンでマークされたように) + +=== :font » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +フォントの種類でテキストを整えます。この文字列は非常に柔軟ですが、"[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]"の形である必要があり、FAMILY-LISTの部分は任意にカンマで終わりカンマで区切られたフォントファミリーの一覧、STYLE_OPTIONSはvariant、weight、stretch、またはgravityなどの空白で区切られたスタイルを表現する単語の一覧、そしてSIZEは(ポイントのサイズの)10進数または絶対的なサイズのために単位修飾子"px"を任意に続けます。オプションのどれかは設定されないかもしれません。FAMILY-LISTが設定されない場合は、デフォルトフォントファミリー(Arial)が利用されます。 + +=== :group » a string === + +''radio''で利用できます。 + +どのグループにラジオボタンが所属するかを示します。この設定がない場合は、ラジオボタンは周辺のスロットのラジオボタンとグループ化されます。ラジオボタンを"グループ化"することはスクリーン上でお互いに隣接してグループ化されることを意味するのではありません。それは、一度にグループから一つだけのラジオボタンだけを選択できることを意味します。 + +文字列にスタイルを与えることによって、ラジオボタンは同じグループ名を持つ他のラジオボタンとグループ化されます。 + +=== :height » a number === + +''すべてのスロットと要素''で利用できます。 + +オブジェクトの高さをピクセルで設定します。数値が10進数なら、その高さは親の高さのパーセンテージになります。(0.0は0%に、1.0は100%になります。) + +=== :hidden » true or false === + +''すべてのスロットと要素''で利用できます。 + +オブジェクトの表示または非表示です。すべてのオブジェクトにとって`:hidden => true`は画面上での非表示になります。その子供のスロットと要素でも同様です。 + +=== :inner » a number === + +''star''で利用できます。 + +内側の半径のサイズ(ピクセル)です。その内側の半径は点が別れ始める星の中に中空でない円を描きます + +=== :items » an array === + +''list_box''で利用できます。 + +リストボックスの項目の一覧です。例のために[[Element.list_box]]メソッドを見てください。 + +=== :justify » true or false === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +均一に水平にテキストの間隔を開けます。 + +=== :kerning » a number === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +文字の間に自然な空白をピクセルで追加します。 + +=== :leading » a number === + +''banner, caption, inscription, para, subtitle, tagline, title''で利用できます。 + +テキストブロックの行間に空白を設定します。デフォルトは4ピクセルです。 + +=== :left » a number === + +''すべてのスロットと要素''で利用できます。 + +オブジェクトの左の座標を特定のピクセルに設定します。`:left => 10`の設定はそのオブジェクトを含むスロットの左の端からオブジェクトの左の端が10ピクセル離れた位置に配置します。このleftのスタイルが設定されていない(または`nil`が設定される)なら、そのオブジェクトはそれを囲んでいる他のオブジェクトとともに動くでしょう。 + +=== :margin » a number or an array of four numbers === + +''すべてのスロットと要素''で利用できます。 + +マージンは要素の周囲に間隔をあけます。それぞれの要素はleft、top、right、そしてbottomのマージンを持っています。`:margin`スタイルに一つの数が設定されると、要素の周囲の間隔は均一にその数にとなります。言い換えると、`:margin => 8`を設定すると、その要素の周囲のすべてのマージンは8ピクセルの長さに設定されます。 + +このスタイルは4つの数を`[left, top, right, bottom]`の形の配列で与えることもできます。 + +=== :margin_bottom » a number === + +''すべてのスロットと要素''で利用できます。 + +要素の下側(bottom)のマージンをピクセルで設定します。 + +=== :margin_left » a number === + +''すべてのスロットと要素''で利用できます。 + +要素の左側(left)のマージンをピクセルで設定します。 + +=== :margin_right » a number === + +''すべてのスロットと要素''で利用できます。 + +要素の右側(right)のマージンをピクセルで設定します。 + +=== :margin_top » a number === + +''すべてのスロットと要素''で利用できます。 + +要素の上側(top)のマージンをピクセルで設定します。 + +=== :outer » a number === + +''star''で利用できます。 + +星の外側の半径(''全''幅の半分)をピクセルで設定します。 + +=== :points » a number === + +''star''で利用できます。 + +その星はいくつの頂点を持ちますか?`:points => 5`のスタイルは5つの頂点を持つ星を作成します。 + +=== :radius » a number === + +''arc, arrow, background, border, gradient, oval, rect, shape''で利用できます。 + +それらの要素に半径(直径または全幅の半分)を設定します。これを設定することは、この数値の2倍の`:width`と`:height`を設定することと同等です。 + +=== :right » a number === + +''すべてのスロットと要素''で利用できます。 + +要素の右端の座標をピクセルで設定します。その端はコンテナの右端に対して配置されます。そのため、`:right => 0`は、スロットの右端とその右端が接するように要素を配置するでしょう。一方`:right => 20`は要素の右端をそのスロットの右端から左側に向けて20ピクセル離れたところに配置します。 + +=== :rise » a number === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +テキストのフォントを基準から上げたり下げたりします。例えば、[[Element.sup]]は10ピクセルの`:rise`を行います。逆に、[[Element.sub]]の要素は-10ピクセルの`:rise`となります。 + +=== :scroll » true or false === + +''flow, stack''で利用できます。 + +スロットをスクロールするスロットとします。`:scroll => true`が設定され、そのコンテンツがスロットの高さ以上の場合はスクロールバーがスロットに表示されます。スクロールバーは必要に応じて表示したり非表示になります。それはスロットの幅の内側で表示されるので、スクロールバーのあるなしに関わらず、スロットの幅は決して変わらないことを意味します。 + +=== :secret » true or false === + +''ask, edit_line''で利用できます。 + +Used for password fields, this setting keeps any characters typed in from becoming visible on the screen. Instead, a replacement character (such as an asterisk) is show for each letter typed. + +パスワードフィールドのために利用され、この設定は入力された文字を画面上で表示されないようにします。そのかわり、置き換えられた文字(たとえばアスタリスク)をそれぞれの文字が入力されるごとに表示します。 + +=== :size » a number === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +このテキストブロックまたはテキストの一部の内部で利用されたフォントのサイズをピクセルで設定します。 + +フォントサイズは次の文字列を利用することでも大きくすることができるかもしれません: + + * "xx-small" - 現在のサイズの57% + * "x-small" - 現在のサイズの64% + * "small" - 現在のサイズの83% + * "medium" - サイズ変更なし + * "large" - 現在のサイズの120% + * "x-large" - 現在のサイズの143% + * "xx-large" - 現在のサイズの173% + +=== :state » a string === + +''button, check, edit_box, edit_line, list_box, radio''で利用できます。 + +この`:state`スタイルは編集されたくないコントロールを利用不能または固定するためにあります。 + +利用可能なスタイルの設定: + + * nil - コントロールはアクティブで編集可能です。 + * "readonly" - コントロールはアクティブですが編集不可能です。 + * "disabled" - コントロールはアクティブはなく(グレイアウト)、編集不可能です。 + +=== :stretch » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +テキストオブジェクトに伸縮したフォントを設定します。 + +利用可能な設定: + + * "condensed" - 狭い幅の文字 + * "normal" - 標準の幅の文字 + * "expanded" - 広い幅の文字 + +=== :strikecolor » a Shoes::Color === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +テキストに棒線を引いて削除するときの線の色です。 + +=== :strikethrough » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +このテキストに棒線を引いて削除しますか?2つのオプションがあります: + + * "none" - 棒線を引いて削除しません。 + * "single" - 1本の棒線を引いて削除します。 + +=== :stroke » a hex code, a Shoes::Color or a range of either === + +''arc, arrow, banner, border, caption, code, del, em, flow, image, ins, inscription, line, link, mask, oval, para, rect, shape, span, stack, star, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +フォアグラウンドのペンの色です。形状の場合は描かれる線の色です。段落や他のテキストでは、この色で文字が表示されます。 + +=== :strokewidth » a number === + +''arc, arrow, border, flow, image, line, mask, oval, rect, shape, star, stack''で利用できます。 + +描かれる線のピクセルでの太さで、形状の線を特徴付けます。例えば、数値の2が設定されればstrokewidthは2ピクセルになります。 + +=== :text » a string === + +''button, edit_box, edit_line''で利用できます。 + +edit_boxやedit_lineのコンテンツ、またはボタンコントロールに表示されるメッセージを設定します。 + +=== :top » a number === + +''すべてのスロットと要素''で利用できます。 + +オブジェクトの上側の座標を、その親のスロットに対して設定します。オブジェクトに`:top => 40`が設定されたなら、オブジェクトの上端はそのオブジェクトを含むスロットの上端から40ピクセル下に配置されることを意味します。`:top`スタイルが与えられないなら、そのスロットの自然な流れでオブジェクトは自動的に配置されます。 + +=== :undercolor » a Shoes::Color === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +テキストの下線に利用される色です。 + +=== :underline » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +テキストに下線のスタイルを指示します。 + +この設定の選択肢は: + + * "none" - 下線なし。 + * "single" - 途切れのない下線。 + * "double" - 平行な途切れのない2本の下線。 + * "low" - フォントの基準より下の低い下線。(一般的に1つの文字に対してだけ、得にキーボードアクセラレータを表示するときに推奨されます。) + * "error" - 波状の下線、通常はミススペルの指摘を見つけます。 + +=== :variant » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +テキストのグループのためにフォントを変化させます。2つの選択肢: + + * "normal" - 通常のフォント。 + * "smallcaps" - 大文字が小さく変化することによって置き換えられた小文字のフォント。 + +=== :weight » a string === + +''banner, caption, code, del, em, ins, inscription, link, para, span, strong, sub, sup, subtitle, tagline, title''で利用できます。 + +Set the boldness of the text. Commonly, this style is set to one of the following strings: +テキストを太文字に設定します。一般的には、このスタイルは次の文字列の内の1つを設定します: + + * "ultralight" - 超軽量の太さ (= 200) + * "light" - 軽量の太さ (=300) + * "normal" - 通常の太さ (= 400) + * "semibold" - 通常と太文字の中間の太さ (=600) + * "bold" - 太文字 (= 700) + * "ultrabold" - 極端な太文字の太さ (= 800) + * "heavy" - 重厚な太さ (= 900) + +しかしながら、数値で太さを直接渡すこともできます。 + +=== :width » a number === + +''すべてのスロットと要素''で利用できます。 + +要素の幅をピクセルで設定します。数値が10進数なら、その幅はパーセンテージに変換されます。(0.0は0%に、1.0は100%になります。)100%の幅は親のスロットを埋め尽くすことを意味します。 + +== Classes List == + +Shoesで紹介するすべてのクラスの完全な一覧です。この表はどのようにしてクラスがお互いに継承しているかに従ってレイアウトされています。サブクラスは親クラスの下に、1レベル右にインデントされています。 + +{INDEX} + +== Colors List == + +以下はShoes全体で利用可能な色の一覧です。背景色または枠線の色として。描かれる線や塗りつぶされる色として。これらの色の大部分はX11やHTMLのパレットから来ています。 + +これらの色はすべて名前によって利用できます。(そのため、どんなスロットの内部からでも`tomato`メソッドを呼ぶことで、すてきな赤みがかった色が手に入るでしょう。)それぞれの色の下には、[[Built-in.rgb]]メソッドで利用できる正確な数値を見つけることもできます。 + +{COLORS} + += Slots = + +スロットは画像やテキストなどのレイアウトに使われる箱です。2つの最も一般的なスロットは`スタック(stack)`と`フロー(flow)`です。スロットはShoesの専門用語で"箱"または"キャンバス"とも言えます + +マウスホイールやページアップやページダウンはあらゆるプラットフォームで普及しているため、縦のスクロールだけが溢れて問題になりました。そのためShoesでは、まさにWEBのように通常は幅が固定です。一方で高さは際限なく続いて行きます。 + +さて、そうしたいなら、どんなものでも幅や高さを指定することもできます。それはいくらかの数学を用いるでしょうが、完璧かもしれません。 + +一般的には、スタックとフローを使うことを提案するでしょう。ここでの目的は、あなたがいくらかの幅を何かで満たして、幅を満たしながら、ページの下に進みたいということです。これらを、HTMLの"ブロック"と"インライン"のスタイルと類似しているのように考えることができます。 + +==== Stacks ==== + +スタックは単純に要素の垂直なスタックです。スタック内のそれぞれの要素は、その上位の要素の直下に配置されます。 + +また、スタックは箱のように形作られます。そのため、スタックが250の幅を与えられたら、そのスタックはそれ自身が250ピクセルの幅の要素となります。 + +新しいスタックを作成するには[[Element.stack]]メソッドを利用し、それはすべてのスロットの内部で利用できます。そのためスタックは他のスタックやフローを含むことができます。 + +==== Flows ==== + +フローは要素をできるだけしっかりと詰め込みます。幅は満たされ、それらの下の要素を包みます。互いに隣接して配置されたテキストの要素は一つのパラグラフとして表示されます。画像とウィジェットは同じシリーズとして実行されます。 + +スタックのように、フローは箱です。そのためスタックとフローは安全に埋め込むことができ、それらのコンテンツに気を使うことなく、同質です。スタックとフローはそれらのコンテンツだけを異なって扱います。 + +フローを作成するには[[Element.flow]]を呼びます。フローは他のフローやスタックを含むかもしれません。 + +最後に:Shoesのウィンドウはそれ自身がフローです。 + +== Art for Slots == + +それぞれのスロットは、色のついた形状やグラデーションなどでおおうことにできる白紙の表面のキャンバスのようなものです。 + +多くの一般的な形状は`oval`と`rect`メソッドで描かれます。まず、絵筆の色を準備する必要があります。 + +`stroke`コマンドは線の色を設定します。`fill`コマンドは線の内部を塗りつぶすために利用する色を設定します。 + +{{{ + #!ruby + Shoes.app do + stroke red + fill blue + oval :top => 10, :left => 10, + :radius => 100 + end +}}} + +このコードはまわりに赤い線のある青いパイを与えます。100ピクセルの幅で、ウィンドウの左上から南東に少しのピクセルを配置します。 + +上記の`blue`と`red`メソッドはカラーオブジェクトです。どうやって色を混ぜるかはColorsセクションを見てください。 + +==== Processing と NodeBox からのインスピレーション ==== + +この技巧的なメソッドの大抵は文字通りPythonのドローイングキットのNodeBoxから来ています。次に、NodeBoxは多くのアイデアを、グラフィックとアニメーションのためのJavaのような言語であるProcessingから得ています。私はそれらのすばらしいプログラムの作者から大きな恩を受けています。 + +ShoesはNodeBoxとProcessingから少しの点が違います。例えば、Shoesはそれ自身のカラーオブジェクトを持っていることを含めて、異なるカラーメソッドを持っていますが、それらはとてもProcessingのカラーメソッドに似ています。そしてShoesは線を描くことや形状内を塗りつぶすために画像やグラデーションを利用することも許しています。 + +ShoesはいくつかのアニメーションのアイデアをProcessingから取り入れており、Processingのメソッドをしっかりと参考にしようとしながらそれを拡張しています。 + +=== arc(left, top, width, height, angle1, angle2) » Shoes::Shape === + +弧の形状(楕円形の一部)を座標(left, top)に描きます。このメソッドは`:angle1`と`:angle2`のスタイルを提供することにより [[oval]]より少し多くの制御をが行えます。(実際には、`:angle1`に0と`:angle2`に`Shoes::TWO_PI`を設定することにより、`oval`メソッドをまねることができます。) + +=== arrow(left, top, width) » Shoes::Shape === + +座標(left, top)に`width`ピクセルの矢を描きます。 + +=== cap(:curve or :rect or :project) » self === + +描くすべての線の終点の形状である線の頂点を設定します。`:curve`が設定されるなら、終点はまるくなります。デフォルトは`:rect`で、線の終点は突然に平らになります。`:project`の頂点も平らですが、棒の外側は少し長くなります。 + +=== fill(pattern) » pattern === + +塗りつぶすバケツの色の指定(またはパターン)を設定します。パターンは色やグラデーションまたは画像が設定できます。そして、一度塗りつぶすバケツが設定されたら、選択されたパターンで色づけられた形状を描くことができます。 + +画像のパターンで星を描くためには: + +{{{ + #!ruby + Shoes.app do + fill "static/avatar.png" + star 200, 200, 5 + end +}}} + +塗りつぶすバケツをクリアするには`nofill`を使ってください。そして`stroke`メソッドを利用して線(星の枠線)の色を設定してください。 + +=== nofill() » self === + +塗りつぶす色を削除するため、形状は塗りつぶされずに描かれます。その代わりに、形状は線だけを持ち、中央を透明のままにします。 + +=== nostroke() » self === + +線の色を空にします。形状は外側の線が描かれなくなります。`nofill`も設定された場合は、形状は表示されずに描かれます。 + +=== line(left, top, x2, y2) » Shoes::Shape === + +現在の線の色(別名"stroke")を使って座標(left, top)から(x2, y2)まで線を描きます。 + +=== oval(left, top, radius) » Shoes::Shape === + +座標(left, top)ピクセルに`radius`ピクセルの幅と高さの円を描きます。線の色や塗りつぶす色が形状を描くために利用されます。デフォルトでは、座標は楕円形の最も左上の角ですが、これは[[Art.transform]]メソッドを呼ぶことや、次のメソッドの下の`:center`スタイルを使用することによって変更することができます。 + +{{{ + #!ruby + Shoes.app do + stroke blue + strokewidth 4 + fill black + + oval 10, 10, 50 + end +}}} + +様々な比率の楕円形を描くためには、`oval(left, top, width, height)`のシンタックスを利用してもいいです。 + +=== oval(styles) » Shoes::Shape === + +スタイルのハッシュを利用して円を描きます。次のスタイルがサポートされています: + + * `top`: 楕円形の囲いのy座標。 + * `left`: 楕円形の囲いのx座標。 + * `radius`: 円の幅と高さ。 + * `width`: 楕円形の幅のピクセルでの指定。 + * `height`: 楕円形の高さのピクセルでの指定。 + * `center`: 座標を楕円形の中央に指定しますか?(trueまたはfalse) + +これらのスタイルはShoesオブジェクトの`style`メソッドを利用して変更されます。 + +=== rect(top, left, width, height, corners = 0) » Shoes::Shape === + +座標(left, top)からwidth x heightの寸法の長方形を描きます。オプションとして、5番目の引数(ピクセルでの角の半径)により長方形の角を丸くすることもできます。他の形状と同様に、長方形は描く線の色や塗りつぶす色を利用して描かれます。 + +{{{ + #!ruby + Shoes.app do + stroke rgb(0.5, 0.5, 0.7) + fill rgb(1.0, 1.0, 0.9) + rect 10, 10, self.width - 20, self.height - 20 + end +}}} + +上記のサンプルは角の周囲に10ピクセルのマージンを残して、その親の箱の範囲を塗りつぶす長方形を描きます。デフォルトで親の箱を塗りつぶした長方形のためには`background`も見てください。 + +=== rect(styles) » Shoes::Shape === + +スタイルのハッシュを利用して長方形を描きます。次のスタイルがサポートされています: + + * `top`: 長方形のy座標。 + * `left`: 長方形のx座標。 + * `curve`: 長方形の角の半径のピクセル。 + * `width`: 長方形のピクセルによる幅。 + * `height`:長方形のピクセルによる高さ。 + * `center`: 座標を長方形の中央に指定しますか?(trueまたはfalse) + +これらのスタイルはShoesオブジェクトの`style`メソッドを利用して変更されます。 + +=== rotate(degrees: a number) » self === + +形状をその角度で描画するために、`度(degrees)`数により描画のために利用される範囲を回転させます。 + +下の例では、長方形は(30, 30)に45度回転されて描かれます。 + +{{{ + #!ruby + Shoes.app do + fill "#333" + rotate 45 + rect 30, 30, 40, 40 + end +}}} + +=== shape(left, top) { ... } » Shoes::Shape === + +(left, top)から開始してブロックの内部で`line_to`、`move_to`、`curve_to`そして`arc_to`を呼ぶことにより +続く、描かれる任意の形状を表現(記述)します + +曲がったり弧を描いたりする長い線の形状をスケッチとして見ることができます。 + +{{{ + #!ruby + Shoes.app do + fill red(0.2) + shape do + move_to(90, 55) + arc_to(50, 55, 50, 50, 0, PI/2) + arc_to(50, 55, 60, 60, PI/2, PI) + arc_to(50, 55, 70, 70, PI, TWO_PI-PI/2) + arc_to(50, 55, 80, 80, TWO_PI-PI/2, TWO_PI) + end + end +}}} + +形状は他の形状を含むこともできます。そして、形状の内部に[[Art.oval]]、[[Art.rect]]、[[Art.line]]、[[Art.star]]または[[Art.arrow]](さらに、[[Art]]セクションの他のメソッドすべて)を配置することができますが、それらは線の一部ではないでしょう。形状のグループのようなそれらは、すべて1つとして描かれます。 + +=== star(left, top, points = 10, outer = 100.0, inner = 50.0) » Shoes::Shape === + +描く線の色や塗りつぶす色を利用して星を描きます。星は(left, top)の座標を中心点として`頂点(points)`の数とともに配置されます。`outer`の幅は星の全半径をを定義します;`inner`の幅は頂点の始まる星の中央の半径を指定します。 + +=== stroke(pattern) » pattern === + +スロットのアクティブな線の色を設定します。`pattern`は色、グラデーションまたは画像で、それらはすべて"patterns"に分類されます。その線の色はそれに続く形状すべての枠線を描くときに利用されます。 + +つまり、まわりに赤い線を持つ矢印を描くには: + +{{{ + #!ruby + Shoes.app do + stroke red + arrow 0, 100, 10 + end +}}} + +線の色をクリアするには、`nostroke`メソッドを利用します。 + +=== strokewidth(a number) » self === + +スロットの内部で描かれるすべての線のサイズを設定します。`stroke`メソッドが線の色を変更する一方、`strokewidth`メソッドは線のサイズをピクセルで変更します。`strokewidth(4)`を呼ぶことにより4ピクセルの太さで線を描きます。 + +=== transform(:center or :corner) » self === + +(`skew`や`rotate`のような)変化は形状の中心あたりで実行されるべきですか?またはその形状の角ですか?Shoesの初期値は`:corner`です。 + +=== translate(left, top) » self === + +スロットの描画の範囲を開始する位置を移動します。通常は、すべての形状がこの位置から描くことができるように、その範囲は左上の角の(0, 0)から開始します。`translate`により開始位置が(10, 20)に移動されて、(50, 60)に形状が描かれるなら、その形状は実際にはスロットの(60, 80)に描かれます。 + +== Element Creation == + +Shoesは幅広い種類の要素を持っており、その多くをHTMLからよいところを選んで採用しています。このページはどのようにしてスロットにそれらの要素を作成するかを記述しています。それらの要素を配置した後でさらにどのようにして変更したり利用するのかについては、このマニュアルの要素(Elements)のセクションを見てください。 + +=== animate(fps) { |frame| ... } » Shoes::Animation === + +アプリケーションをそのままにして並列で実行するアニメーションタイマーを開始します。`fps`は秒ごとのフレームの数です。この数は付属するブロックが1秒に何回呼ばれるのかを決定します。 + +このブロックは`frame`の数が与えられます。`frame`の数はゼロから始まり、そのブロックが何フレームのアニメーションを表示したのかを教えます + +{{{ + #!ruby + Shoes.app do + @counter = para "STARTING" + animate(24) do |frame| + @counter.replace "FRAME #{frame}" + end + end +}}} + +上記のアニメーションは1秒間に24回表示されます。数が与えられないなら、`fps`のデフォルトは10です。 + +=== background(pattern) » Shoes::Background === + +色(またはパターン)を指定して背景(Background)要素を描きます。パターンは色、グラデーションまたは画像です。色と画像は背景全体に敷き詰めます。グラデーションは背景を塗りつぶすように伸びます。 + +'''注意してください:''' 背景は実際には要素であり、スタイルではありません。HTMLは背景をスタイルのようにあつかいます。それはすべての箱は一つの背景だけを持てることを意味します。Shoesは背景の要素を重ねることができます。 + +{{{ + #!ruby + Shoes.app do + background black + background white, :width => 50 + end +}}} + +上記の例は二つの背景を塗ります。まず、黒い背景がアプリケーションの表面のエリア全体に塗られます。そして、50ピクセルの白い縞が左側にそって塗られます。 + +=== banner(text) » Shoes::Banner === + +バナー(Banner)のテキストブロックを作成します。Shoesは自動的に48ピクセルの大きさにテキストを整形します。 + +=== border(text, :strokewidth => a number) » Shoes::Border === + +色(またはパターン)を指定して枠線(Border)の要素を描きます。パターンは色、グラデーションまたは画像です。色と画像は枠線全体に敷き詰めます。グラデーションは背景を塗りつぶすように伸びます。 + +'''注意してください:''' 背景のように、枠線は実際には要素であり、スタイルではありません。HTMLは背景や枠線をスタイルのようにあつかいます。それはすべての箱は一つの枠線だけを持てることを意味します。Shoesはテキストブロック、画像、他のすべてのものにそって、枠線や背景の要素を重ねることができます。 + +=== button(text) { ... } » Shoes::Button === + +表面にわたってメッセージ`テキスト(text)`の書かれた押しボタンを追加します。 +ボタンが押されたときに呼ばれる、任意のブロックを取り付けることができます。 + +=== caption(text) » Shoes::Caption === + +キャプション(Caption)テキストブロックを作成します。Shoesは14ピクセルの大きさにこのテキストを整形します。 + +=== check() » Shoes::Check === + +チェックボックスを追加します。 + +=== code(text) » Shoes::Code === + +コード(Code)のテキストの一部を作成します。このテキストはデフォルトで等幅フォントになります。 + +=== del(text) » Shoes::Del === + +デフォルトで中央に1本の棒線を引いてテキストを削除した、削除された(Del)("deleted"の省略形)テキストの一部を作成します。 + +=== dialog(styles) { ... } » Shoes::App === + +(まさに [[Element.window]]メソッドを実効したように)新しいアプリケーションのウィンドウを開きますが、そのウィンドウはダイアログボックスの外観を与えられます。 + +=== edit_box(text) » Shoes::EditBox === + +スロットに大きなマルチラインのテキストエリアを追加します。 +この`text`はオプションでこの箱の開始時に与えられる文字列です。 +オプションのブロックをここに取り付けることができ、これはボックスのテキストに対するどんな種類のユーザの変更でも呼び出されます。 + +{{{ + #!ruby + Shoes.app do + edit_box + edit_box "HORRAY EDIT ME" + edit_box "small one", :width => 100, :height => 160 + end +}}} + +=== edit_line(text) » Shoes::EditLine === + +スロットに一行のテキストボックスを追加します。 +この`text`はオプションでこの箱の開始時に与えられる文字列です。 +オプションのブロックをここに取り付けることができ、これはボックスのテキストに対するどんな種類のユーザの変更でも呼び出されます。 + +=== em(text) » Shoes::Em === + +Em("emphasized"の省略形)テキストの一部を作成し、これはデフォルトでイタリック体で整形されます。 + +=== every(seconds) { |count| ... } » Shoes::Every === + +`animation`メソッドとよく似たタイマーですが、より非常に遅いです。このタイマーは与えられた数の秒(seconds)で、取り付けられたブロックを実行します。そのため、例えば5秒毎にwebサイトを確認する必要があるなら、実際にwebサイトにpingを打つコードを含むブロックと共に`every(300)`を呼び出します。 + +=== flow(styles) { ... } » Shoes::Flow === + +フロー(flow)はShoesの要素を配置できる目に見えない箱(または"スロット")です。フローとスタックのどちらもメインの[[Slots]]のページでとても詳細に説明されます。 + +フローは要素を水平にまとめます。ものを垂直に積み重ねたままにするために[[Element.stack]]を利用するところで、フローはそのコンテンツをページの端から端にわたって配置します。いったんページの最後に到達したら、フローは要素の新しい行を開始します。 + +=== image(path) » Shoes::Image === + +写真を表示するために[[Image]]の要素を作成します。 +PNG、JPEGそしてGIFのフォーマットが許されます。 + +`path`はファイルのパスまたはURLです。すべての画像はメモリに一時的にキャッシュされ、リモートの画像はローカルのユーザの個人的なShoesディレクトリにもキャッシュされます。リモートの画像はバックグラウンドでロードされます;ブラウザと同様に、画像はすぐには表示されませんが、それらがロードされたときに表示されます。 + +=== imagesize(path) » [width, height] === + +画像の幅と高さを素早く手に入れます。 +画像はキャッシュにロードされず表示もされません。 + +緊急の注意:このメソッドはリモートの画像(ハードディスクドライブからではなくHTTPによりロードされた)には利用できません。 + +=== ins(text) » Shoes::Ins === + +一本の下線のShoesスタイルである、Ins("inserted"の省略形)テキストの一部を作成します。 + +=== inscription(text) » Shoes::Inscription === + +題名(Inscription)のテキストブロックを作成します。Shoesは10ピクセルの大きさにこのテキストを整形します。 + +=== link(text, :click => proc or string) » Shoes::Link === + +一本の下線を持ち線の色を#06E(青色)にShoesが整形した、リンクテキストブロックを作成します。デフォルトのリンクホバースタイルも一本の下線を持ち線の色を#039(ダークブルー)に整形します。 + +=== list_box(:items => [strings, ...]) » Shoes::ListBox === + +`items`の配列のすべてのエントリを含むドロップダウンリストボックスを追加します。オプションでブロックが取り付けることができ、これはユーザがボックスの項目を選択したら呼び出されます。 + +{{{ + #!ruby + Shoes.app do + stack :margin => 10 do + para "Pick a card:" + list_box :items => ["Jack", "Ace", "Joker"] + end + end +}}} + +選択された文字列をを得るために`ListBox#text`を呼び出します。より多くのヘルプは`リストボックス(ListBox)`のセクションの`ネイティブ`コントロールを見てください。 + +=== progress() » Shoes::Progress === + +プログレスバーを追加します。 + +=== para(text) » Shoes::Para === + +Shoesが12ピクセルの大きさに整形する、Para("paragraph"の省略形)テキストブロックを作成します。 + +=== radio(group name: a string or symbol) » Shoes::Radio === + +ラジオボタンを追加します。`グループ名(group name)`が与えられたら、ラジオボタンはグループの一部だとみなされます。同じグループのラジオボタンのうちで、1つだけをクリックすることができます。(もしグループ名が与えられなければ、そのラジオボタンは同じスロットの他のすべてのラジオボタンとグループ化されます) + +=== span(text) » Shoes::Span === + +デフォルトでされない、Spanテキストの一部を作成します。 + +=== stack(styles) { ... } » Shoes::Stack === + +新しいスタックを作成します。スタックはスロットの一種です。(スタックとフローの完全な説明はメインの[[Slots]]のページを見てください。) + +要するに、スタックは要素を配置するための目に見えない箱("スロット")です。スタックにボタンや画像などを追加して、それらは垂直に積み上げられます。そう、それらは重なります。 + +=== strong(text) » Shoes::Strong === + +デフォルトで太字に整形された、Strongテキストの一部を作成します。 + +=== sub(text) » Shoes::Sub === + +デフォルトでテキストは10ピクセル(位置を)下げられx-smallフォントに整形された、Sub("subscript"の省略形)テキストの一部を作成します。 + +=== subtitle(text) » Shoes::Subtitle === + +サブタイトル(Subtitle)テキストブロックを作成します。Shoesは26ピクセルの大きさにこのテキストを整形します。 + +=== sup(text) » Shoes::Sup === + +デフォルトでテキストは10ピクセル(位置を)上げられx-smallフォントに整形された、Sup("superscript"の省略形)テキストの一部を作成します。 + +=== tagline(text) » Shoes::Tagline === + +タグライン(Tagline)テキストブロックを作成します。Shoesはこのテキストを18ピクセルの大きさに整形します。 + +=== timer(seconds) { ... } » Shoes::Timer === + +1回だけのタイマーです。少しの秒(または分、時)後にいくらかのコードの実行をスケジュールしたいなら、ここにブロックとしてコードを取り付けることができます。 + +今から5秒後にアラートボックスを表示するためには: + +{{{ + #!ruby + Shoes.app do + timer(5) do + alert("Your five seconds are up.") + end + end +}}} + +=== title(text) » Shoes::Title === + +タイトル(Title)テキストブロックを作成します。Shoesはこれらの要素を34ピクセルの大きさに整形します。 + +=== video(path or url) » Shoes::Video === + +スロットに動画を埋め込みます。 + +=== window(styles) { ... } » Shoes::App === + +新しいアプリケーションウィンドウを開きます。このメソッドは初めにアプリケーションを開始するために使われる[[App.Shoes.app]]メソッドとほとんど同一です。違いは`window`メソッドは新しいウィンドウの[[App.owner]]プロパティを設定することです。(普通のShoes.appはその`owner`を`nil`に設定します。) + +そのため、新しいウィンドウの`owner`はウィンドウを開始したShoes::Appに設定されるでしょう。この方法により子のウィンドウが親を呼べます。 + +{{{ + #!ruby + Shoes.app :title => "The Owner" do + button "Pop up?" do + window do + para "Okay, popped up from #{owner}" + end + end + end +}}} + +== Events == + +どのようにしてマウスのクリックを離したことやキーボードをタイプしたことが分かるか不思議に思いませんか?スロットの内部でマウスが動いたときはいつでもイベントがスロットに送られます。また、キーが押されたときはいつでも。スロットが作成されたり破壊されたときでさえ。それぞれのそれらのイベントをブロックを取り付けることができます。 + +マウスイベントは`motion`、`click`、`hover`そして`leave`を含みます。キーボードのタイピングは`keypress`イベントによって表されます。そして`start`や`finish`イベントはキャンバスを開始するときや破棄されたときを指し示します。 + +では、マウスでスロットの上をフロートするときに背景を変更したいとしましょう。スロットの内部にマウスがくるときに背景を変更するためには`hover`イベントを使います。そして、マウスがフロートして離れるときに戻すには`leave`を使います。 + +{{{ + #!ruby + Shoes.app do + s = stack :width => 200, :height => 200 do + background red + hover do + s.clear { background blue } + end + leave do + s.clear { background red } + end + end + end +}}} + +=== click { |button, left, top| ... } » self === + +マウスボタンがクリックされたときにはclickブロックが呼ばれます。`button`はマウスボタンのどれが押されたかの数です。`left`や`top`はどこがクリックされたかのマウスの座標です。 + +マウスのクリックを離した瞬間をとらえるには、[[Events.release]]イベントを見てください。 + +=== finish { |self| ... } » self === + +スロットが取り除かれたときは、finishイベントが発生します。finishブロックはすぐに`self`を手渡し、スロットオブジェクトは取り除かれます。 + +=== hover { |self| ... } » self === + +hoverイベントはスロットにマウスが入ったときに発生します。 +このブロックは`self`を手に入れ、どのオブジェクトの上を通ったかを意味します。 + +スロットからマウスが出ていくことをとらえるには、[[Events.leave]]イベントを確認してください。 + +=== keypress { |key| ... } » self === + +キー(またはキーの組み合わせ)がいつ押されても、そのブロックは呼ばれます。そのブロックはキーの性質を表す文字列である`key`を送ります。特別なキーやキーの組み合わせの場合は、文字列ではなくRubyのシンボルが送られます。 + +そして、例えば、`Shift-a`が押されたなら、そのブロックは`"A"`の文字列を得ます。 + +しかしながら、F1が押されたなら、 `:f1`のシンボルを受けとります。`Shift-F1`なら、そのシンボルは`:shift_f1`です。 + +`control`、`shift`そして`alt`は修飾キーです。それらは以下の順番で現れます。`Shift-Control-Alt-PgUp`が押されたなら、そのシンボルは`:control_shift_alt_page_up`になります。 + +シフトキーについて1つ。多くのキーでシフトキーを見ないでしょう。USキーボードでは、`Shift-7`はアンパサンド(&)です。そのため、`:shift_5`ではなく`"&"`を得ます。そして、そのようなキーボードで`Shift-Alt-7`を押したら、`:alt_&`のシンボルを得ます。いくつか下のパラグラフで特別なキーのシフト修飾子の一覧が見えます。 + +{{{ + #!ruby + Shoes.app do + @info = para "NO KEY is PRESSED." + keypress do |k| + @info.replace "#{k.inspect} was PRESSED." + end + end +}}} + +Shoesがそれ自身のいくつかのホットキーを利用することを覚えておいてください。Alt-ピリオド(`:alt_.`)、Alt-クエッション(`:alt_?`)そしてAlt-スラッシュ(`:alt_/`)はShoesの予約語です。 + +以下はスペシャルキーの一覧です: `:escape`、`:delete`、 +`:backspace`、`:tab`、`:page_up`、`:page_down`、`:home`、`:end`、`:left`、`:up`、 +`:right`、`:down`、`:f1`、`:f2`、`:f3`、`:f4`、`:f5`、`:f6`、`:f7`、`:f8`、`:f9`、 +`:f10`、`:f11`そして`:f12`。 + +それらすべてのルールに関する一つの警告:通常はリターンキーは`"\n"`を与えます。しかしながら、修飾キーが押されたときには、最後には`:control_enter`、`:control_alt_enter`、`:shift_alt_enter`になります。 + +=== leave { |self| ... } » self === + +スロットからマウスカーソルが出て行くときleaveイベントが発生します。その瞬間すでにマウスカーソルはスロットの端の中にはありません。leaveイベントが発生するとき、`self`とともにブロックが呼ばれ、そのスロットオブジェクトは取り残されます。 + +スロットにマウスが入ることを見つけたいなら[[Events.hover]]も見てください。 + +=== motion { |left, top| ... } » self === + +マウスがスロットの内部を移動するたびにモーションのブロックは呼ばれます。ブロックはカーソルの`left`や`top`の座標を渡します。 + +{{{ + #!ruby + Shoes.app :width => 200, :height => 200 do + background black + fill white + @circ = oval 0, 0, 100, 100 + + motion do |top, left| + @circ.move top - 50, left - 50 + end + end +}}} + +=== release { |button, left, top| ... } » self === + +マウスがアンクリック(マウスアップ)のときにreleaseのブロックは実行されます。それは指が持ち上げられたときです。`button`は押し下げられたボタンに対応する数です。`left`や`top`はボタンが離されたときのマウスのの座標です。 + +実際のマウスクリックを捕まえるには、[[Events.click]]イベントを利用してください。 + +=== start { |self| ... } » self === + +初めてスロットが描かれるとき、スタート(start)イベントが実行されます。まさに今描かれたスロットオブジェクトが`self`としてブロックに渡されます。 + +== Manipulation Blocks == + +以下のmanipulationメソッドはスロットの周囲を変更したり新しい要素を挿入することを手早く片付けます。 + +=== append() { ... } » self === + +スロットの最後に要素を追加します。 + +{{{ + #!ruby + Shoes.app do + @slot = stack { para 'Good Morning' } + timer 3 do + @slot.append do + title "Breaking News" + tagline "Astronauts arrested for space shuttle DUI." + end + end + end +}}} + +`title`や`tagline`の要素を`@slot`の最後に追加します。 + +=== after(element) { ... } » self === + +スロットの子として`element`のすぐ後に、スロットの指定した箇所に要素を追加します。 + +=== before(element) { ... } » self === + +スロットの子として`element`のすぐ前に、スロットの指定した箇所に要素を追加します。 + +=== clear() » self === + +タイマーやネストしたスロットなど、スロットのすべての要素を空にします。スロットのコンテンツを最初から最後までループしてそれぞれの要素の`remove`メソッドを呼ぶことと効果としては同一です。 + +=== clear() { ... } » self === + +clearメソッドはオプションでブロックも取ります。このブロックはスロットのコンテンツを置き換えるために利用されます。 + +{{{ + #!ruby + Shoes.app do + @slot = stack { para "Old text" } + timer 3 do + @slot.clear { para "Brand new text" } + end + end +}}} + +この例では、"Old text"パラグラフは排除され、"Brand new text"によって置き換えられます。 + +=== prepend() { ... } » self === + +スロットの初めに要素を追加します。 + +{{{ + #!ruby + Shoes.app do + @slot = stack { para 'Good Morning' } + timer 3 do + @slot.prepend { para "Your car is ready." } + end + end +}}} + +`@slot`の初めに`para`要素を追加します。 + +== Position of a Slot == + +他のすべての要素と同様に、スロットは作成されたときに整形することやカスタマイズすることができます。 + +スタックの幅を150ピクセルに設定するためには: + +{{{ + #!ruby + Shoes.app do + stack(:width => 150) { para "Now that's precision." } + end +}}} + +それぞれのスタイルの設定は、詳細な設定を手に入れるために利用することのできるメソッドも持っています。(そのため、例えば、`width`メソッドはスロットの幅をピクセルで返します。) + +=== displace(left: a number, top: a number) » self === + +:displace_leftと:displace_topスタイルの設定のためのショートカットメソッドです。置き換えはレイアウトを変更しないでスロットを移動する便利な方法です。実際には、`top`と`left`メソッドは置き換えを全く報告しません。そのため、通常、置き換えは一時的なアニメーションのためにあります。例えば、適当な位置にボタンを少し移動するなど。 + +`left`と`top`の数は`displace`に送られ、スロット自身のtopとleftの座標に追加されます。topとleftの座標から差し引くには、負数を利用してください。 + +=== gutter() » a number === + +スクロールバーエリアの大きさです。Shoesがスクロールバーを表示する必要があるとき、スクロールバーがウィンドウの端にふれているいくつかの要素を隠してしまうかもしれません。`gutter`はどのくらいのピクセルをスクロールバーが隠すことを期待するかを教えます。 + +これは一般的には、次のように右側に詰め物の要素として利用します: + +{{{ + #!ruby + Shoes.app do + stack :margin_right => 20 + gutter do + para "Insert fat and ratified declaration of independence here..." + end + end +}}} + +=== height() » a number === + +スロットの目に見えるピクセルでの垂直の大きさです。そして、スクロールするスロットの場合は、スロットの全体の大きさを得るために`scroll_height()`の利用を必要とするでしょう。 + +=== hide() » self === + +見えなくするために、スロットを隠します。[[Position.show]]と[[Position.toggle]]も見てください。 + +=== left() » a number === + +The left pixel location of the slot. Also known as the x-axis coordinate. +スロットの位置の左のピクセルです。x-axis座標でも知ることができます。 + +=== move(left, top) » self === + +スロットの左上の角である(left、top)の座標を指定してスロットを移動します。 + +=== remove() » self === + +スロットを削除します。それは表示されなくなり親のコンテンツに記載されなくなります。それは消え去ります。 + +=== scroll() » true or false === + +スロットにスクロールバーを表示することを許しますか?trueかfalseです。スロットの高さも固定されているときだけスクロールバーが表示されます。 + +=== scroll_height() » a number === + +スクロールによって隠されているすべてを含む、スロット全体の垂直の大きさです。 + +=== scroll_max() » a number === + +このスロットでスクロールダウンできる上側(top)の座標です。スクロールバーの上側(top)の座標はいつもゼロです。下側(bottom)の座標はスロット全体の高さから1ページのスクロール分を引いたものです。この下側(bottom)の座標は`scroll_max`が返す値です。 + +これは基本的に`slot.scroll_height - slot.height`と書くためのショートカットです。 + +スロットの下側にスクロールするためには、`slot.scroll_top = slot.scroll_max`を利用します。 + +=== scroll_top() » a number === + +スロットがスクロールダウンする上側(top)の座標です。そのため、スロットが20ピクセルスクロールダウンされたら、このメソッドは`20`を返します。 + +=== scroll_top = a number === + +任意の座標にスロットをスクロールします。ゼロから`scroll_max`までの間である必要があります。 + +=== show() » self === + +スロットが隠されていた場合、表示します。[[Position.hide]]と[[Position.toggle]]も見てください。 + +=== style() » styles === + +引数なしで`style`メソッドを呼ぶことでスロットに現在適用されているスタイルのハッシュを返します。 + +`height`と`width`などのメソッドはスロットの本当のサイズをピクセルで返しますが、`style[:height]`または`style[:width]`を利用することで初めに要求されたサイズを得ることができます。 + +{{{ + #!ruby + Shoes.app do + @s = stack :width => "100%" + para @s.style[:width] + end +}}} + +この例では、このスタックの下のパラグラフは"100%"の文字列を表示します。 + +=== style(styles) » styles === + +ハッシュのスタイル設定を使ってスロットを修正してください。このページのどんなメソッドでも(もちろん、このメソッドは除いて)スタイルの設定に利用できます。そして、例えば、`width`メソッドがあり、このように`width`スタイルもあります。 + +{{{ + #!ruby + Shoes.app do + @s = stack { background green } + @s.style(:width => 400, :height => 200) + end +}}} + +=== toggle() » self === + +スロットが表示されているなら非表示にします。また、スロットが非表示なら表示します。 + +=== top() » a number === + +スロットの上(top)の位置です。y軸の座標としても知られています。 + +=== width() » a number === + +スロットの水平のピクセルサイズです。 + +== Traversing the Page == + +スロット内部の要素を最初から最後までループする必要性に気づくかもしれません。または、ページを登って要素の親のスタックを探す必要があるかもしれません。 + +すべての要素で、上位のスロット直接得るために`parent`メソッドを呼ぶことができます。そしてスロットでは、すべての子を得るために`contents`メソッドを呼ぶことができます。(テキストブロックなどのいくつかの要素は、それらの子を得るための`contents`メソッドも持っています。) + +=== contents() » an array of elements === + +スロットのすべての要素を一覧にします。 + +=== parent() » a Shoes::Stack or Shoes::Flow === + +要素のコンテナのオブジェクトを得ます。 + += Elements = + +これはShoesの要素です。要素は楕円の形状と同じくらい単純です。またはビデオストリームと同じくらい複雑です。あなたは以前このマニュアルのスロットのセクションでこれらすべての要素に出会ったことがあります。 + +Shoesは7つのネイティブコントロールを持ちます:ボタン(Button)、エディットライン(EditLine)、エディットボックス(EditBox)、リストボックス(ListBox)、プログレスメータ(Progress meter)、チェックボックス(Check box)、ラジオ(Radio)。私たちの言う"native"コントロールとは、それらの7つの要素がオペレーティングシステムによって描画されることを意味します。そのため、プログレスバーのWindowsでの見え方とOS Xでの見え方は違います。 + +またShoesは7つの他の種類の要素を持っています:背景(Background)、ボーダー(Border)、画像(Image)、形状(Shape)、テキストブロック(TextBlock)、タイマー(Timer)、そしてビデオ(Video)。それらすべてはどんなオペレーティングシステムでも同じような見え方と動きになるべきです。 + +いったん要素を生成した後でも、それを変更したくなるでしょう。それを動かしたり隠したりまたはそれを取り除くために。それらの種類のことを行うために、このセクションのコマンド利用するでしょう。(特にどんな要素上でも利用できるコマンドの[[Common Common Methods]]セクションを確認してください。) + +そして、例として、PNGをスクリーンを配置するためにスロットの`image`メソッドを使ってください。この`image`メソッドはイメージオブジェクトを返します。これらをすっかり変更するためにイメージオブジェクトのこのメソッドを使ってみてください。 + +== Common Methods == + +Shoesでは少しのメソッドがすべての小さな要素によって共有されてます。移動、表示、非表示。要素の削除。基本的でとても一般的なことです。この一覧はそれらの一般的なコマンドを含んでいます。 + +すべてのメソッドの中でもっとも一般的なメソッドの一つは`style`です。(これはスロットの[[Position.style]]メソッドとしてもカバーされます。) + +{{{ + #!ruby + Shoes.app do + stack do + # Background, text and a button: both are elements! + @back = background green + @text = banner "A Message for You, Rudy" + @press = button "Stop your messin about!" + + # And so, both can be styled. + @text.style :size => 12, :stroke => red, :margin => 10 + @press.style :width => 400 + @back.style :height => 10 + end + end +}}} + +個別のコマンドについては、左にあるElementsセクションの他のリンクを見てください。ビデオファイルの中断または再生がしたいなら、ビデオの中断や再生は特異なので、[[Video]]セクションを確認してください。中断するボタンという感じではありません。 + +=== displace(left: a number, top: a number) » self === + +要素を移動して置き換えます。しかし周囲のレイアウトは変更しません。特にアニメーションしている間でも要素の位置を保持したいなら、これは微妙なアニメーションに重要です。おそらく素早く震えるボタンや視界にスロットを滑り込ませるような。 + +要素を置き換えるとき、それが配置されている左上の角から相対的に移動します。そのため、要素が(20, 40)の座標にあり、2ピクセル左と6ピクセル上に置き換えるなら、結果的に(22, 46)の座標となります。 + +{{{ + #!ruby + Shoes.app do + flow :margin => 12 do + # Set up three buttons + button "One" + @two = button "Two" + button "Three" + + # Bounce the second button + animate do |i| + @two.displace(0, (Math.sin(i) * 6).to_i) + end + end + end +}}} + +他の2つのボタンは動かずにじっとしていますが、2番目のボタンが飛び跳ねることに注目してください。この状況で普通の`move`を使うなら、2番目のボタンはレイアウトから取り除かれて、2番目のボタンが全くそこにないかのように振る舞うでしょう。([[Common.move]]の例を見てください。) + +'''特に注意してください:'''表示される要素の座標を得るために`left`と`top`メソッドを利用するなら、通常の座標を得るだけです。それは置き換えが行われていないかのようです。置き換えは即座のアニメーションだけを目的とします。 + +=== height() » a number === + +エレメントの垂直のピクセルによるスクリーンサイズです。画像の場合には、これは画像全体のサイズではありません。これは要素の現在表示されている高さです。 + +150x150ピクセルの画像を持っていて50ピクセルに幅を設定するなら、このメソッドは50を返します。 + +例や他の解説のために[[Common.width]]メソッドも見てください。 + +=== hide() » self === + +要素が見えないように、非表示にします。[[Common.show]]や[[Common.toggle]]も見てください。 + +=== left() » a number === + +要素の左端の位置をピクセルで得ます。 + +=== move(left: a number, top: a number) » self === + +スロットの範囲内でピクセルによって指定した位置に要素を移動します。その要素はスロットの内部にあります。しかし、もはやスロットの他の要素と一緒に積み上げられたりフローされたりしません。その要素は絶対的な位置指定ではなく、自由に浮かんでいます。 + +{{{ + #!ruby + Shoes.app do + flow :margin => 12 do + # Set up three buttons + button "One" + @two = button "Two" + button "Three" + + # Bounce the second button + animate do |i| + @two.move(40, 40 + (Math.sin(i) * 6).to_i) + end + end + end +}}} + +3番目のボタンがその位置にスライドすることを許しており、2番目のボタンは特定の場所に動かされてします。要素を別の場所に変更しないで移動したいなら、[[Common.displace]]メソッドを見てください。 + +=== parent() » a Shoes::Stack or Shoes::Flow === + +その要素のコンテナのオブジェクトを得ます。反対のことを行うためにはスロットの[[Traversing.contents]]も見てください:コンテナの要素を得ます。 + +=== remove() » self === + +スロットから要素を削除します。(他の言葉で言い換えると:ガベージに投げます。)その要素はもう表示されません。 + +=== show() » self === + +要素が非表示なら、表示します。[[Common.hide]]や[[Common.toggle]]も見てください。 + +=== style() » styles === + +ハッシュの形で、要素に適用するフルセットのスタイルを得ます。`width`や`height`や`top`のようなメソッドは特定のピクセルでのサイズを返しますが、`style[:width]`または`style[:top]`を利用すると、初めの設定を得ることができます。("100%"の幅または"10px"のトップのような) + +{{{ + #!ruby + Shoes.app do + # A button which take up the whole page + @b = button "All of it", :width => 1.0, :height => 1.0 + + # When clicked, show the styles + @b.click { alert(@b.style.inspect) } + end +}}} + +=== style(styles) » styles === + +要素のスタイルを変更します。これは要素の`:width`と`:height`、テキストのフォントの`:size`、形状の`:stroke`や`:fill`を含みます。または他の多くのスタイルの設定もです。 + +=== toggle() » self === + +要素が表示されているなら非表示にします。または要素が非表示なら表示します。 + +=== top() » a number === + +要素の上端のピクセルの位置を得ます。 + +=== width() » a number === + +要素の全体の大きさの幅をピクセルで得ます。このメソッドはいつも正確なピクセルサイズを返します。画像の場合は、画像の全幅ではなく、表示されているサイズだけです。詳しくは[[Common.height]]メソッドも見てください。 + +また、120ピクセルの幅のスタック内に100%の幅の要素を作成したなら、`120`が返されます。しかしながら、`style[:width]`を呼んだなら、`"100%"`を得ます。 + +{{{ + #!ruby + Shoes.app do + stack :width => 120 do + @b = button "Click me", :width => "100%" do + alert "button.width = #{@b.width}\n" + + "button.style[:width] = #{@b.style[:width]}" + end + end + end +}}} + +幅を設定するためには、[[Common.style]]メソッドをもう一度調べる必要があります。そして、150ピクセルの幅にボタンを設定するには:`@b.style(:width => 150)`。 + +要素の幅を取るには、設定を空にするために`@b.style(:width => nil)`とします + +== Background == + +背景はスロット全体に渡って塗られた、グラデーションまたは画像の色です。背景と枠線はShoes::Patternの種類の一つです。!{:margin_left => 100}man-ele-background.png! + +''背景(background)''と呼ばれているにも関わらず、この要素は他の要素よりも前面に表示されます。背景がスロットで塗られた何か他のもの(`rect`または`oval`のような)の後にきた場合、背景はその要素の上に塗られます。 + +もっとも単純な背景は、黒の背景のような[[Element.background]]メソッドによって作成された、単色の背景です。 + +{{{ + #!ruby + Shoes.app do + background black + end +}}} + +このような単純な背景はスロットが含むもの全体を塗りつぶします(この場合は、ウィンドウ全体が黒で塗られます。) + +好きなように背景のサイズを切り詰めたりあちこち移動したりするためのスタイルを利用できます。 + +ウィンドウの上側を50ピクセルに渡って黒い背景で塗りつぶします: + +{{{ + #!ruby + Shoes.app do + background black, :height => 50 + end +}}} + +または、ウィンドウの右端の50ピクセルの列を塗りつぶします: + +{{{ + #!ruby + Shoes.app do + background black, :width => 50, :right => 50 + end +}}} + +背景は普通の要素と同様なので、その他のすべてのメソッドについては[[Elements]]セクションの始めの部分も見てください。 + +=== to_pattern() » a Shoes::Pattern === + +背景を塗りつぶすために利用されたグラデーションや画像を通常のShoes::Patternオブジェクトに配置し、色をヤンクします。そして、他のオブジェクトに背景や枠線に渡すことができます。好きなように再利用してください。 + +== Border == + +枠線はスロットの周囲の線に塗られた、色やグラデーションや画像です。次のセクションの背景の要素では、枠線(Border)はShoes::Patternの一種です。!{:margin_left => 100}man-ele-border.png! + +はじめに、すべての枠線はスロットの周囲の外側ではなく、'''内側'''を塗ることについて知ることは重要です。そのため、50ピクセルの幅のスロットに5ピクセルの枠線を塗るなら、それは枠線で囲まれたスロットが内部に40ピクセルの幅のエリアを持つことを意味します。 + +これは枠線(Border)を[[Background]]の上に塗るなら、その背景の端の上を枠線によって塗られることも意味します。 + +正にそのようなスロットがここにあります: + +{{{ + #!ruby + Shoes.app do + stack :width => 50 do + border black, :strokewidth => 5 + para "=^.^=", :stroke => green + end + end +}}} + +スロットの外側の修正に枠線を塗りたいなら、もう一つのスロットでそのスロットをラップする必要があります。その結果、スロットの外側に枠線が配置されます。 + +{{{ + #!ruby + Shoes.app do + stack :width => 60 do + border black, :strokewidth => 5 + stack :width => 50 do + para "=^.^=", :stroke => green + end + end + end +}}} + +HTMLや他の多くの言語では、枠線は箱の外側に塗られるため、ボックス全体の幅が増加します。Shoesは一貫性を考慮してデザインされているため、枠線やマージンや他のどんなものも気にしないでそれは50ピクセルの幅のままです。 + +枠線に利用する他のメソッドについては[[Elements]]セクションも確認してください。 + +=== to_pattern() » a Shoes::Pattern === + +枠線を塗るための色、グラデーションまたは画像を元にした基本のパターンオブジェクトを作成します。 + +== Button == + +ボタン(Button)は、ご存知のとおり、押しボタンです。それらをクリックしたら何かを行います。ボタンは"OK"または"Are you sure?"などを表示します。そして、よければボタンをクリックします。 + +{{{ + #!ruby + Shoes.app do + button "OK!" + button "Are you sure?" + end +}}} + +上記の例のボタンはそれらがクリックされたときに何も行いません。働きを行わせるためには、それぞれのボタンにブロックを取り付けます。 + +{{{ + #!ruby + Shoes.app do + button "OK!" do + append { para "Well okay then." } + end + button "Are you sure?" do + append { para "Your confidence is inspiring." } + end + end +}}} + +このようにボタンにブロックを取り付けました。それぞれのブロックはページに新しいパラグラフを取り付けます。クリックする度に、パラグラフが追加されます。 + +これはこれ以上深くはしません。ボタンはクリック可能な句でしかありません。 + +厳密に言えば、次に続く例では他の方法でそれを書いています。 + +{{{ + #!ruby + Shoes.app do + @b1 = button "OK!" + @b1.click { para "Well okay then." } + @b2 = button "Are you sure?" + @b2.click { para "Your confidence is inspiring." } + end +}}} + +見た目は劇的に違いますが、これは同じ動きです。1つ目の違い:直接ブロックをボタンに取り付けるのではなく、`click`メソッドを通して、ブロックを後で取り付けています。 + +2つ目の違いはボタンには全く関係がありません。Shoesがスロットに要素を直接追加することを許しているので、`append`ブロックが取り除かれています。そのため直接`para`を呼ぶことができます。(`prepend`、`before`または`after`メソッドの場合にはできません。) + +以下のメソッドに加えて、ボタンは[[Common]]のすべてのメソッドも継承します。 + +=== click() { |self| ... } » self === + +ボタンがクリックされたときには、`click`ブロックが呼ばれます。このブロックは`self`を渡します。意味すること:どちらのボタンでクリックされたか。 + +=== focus() » self === + +ボタンのフォーカスを移動します。そのボタンはハイライトされ、ユーザがエンターキーを打てば、クリックされます。 + +== Check == + +チェックボックスはチェックされた状態またはチェックされていない状態になるクリック可能な四角い箱です。1つのチェックボックスでは通常は"はい(yes)"または"いいえ(no)"の質問をたずねます。複数のチェックボックスのセットではto-doリストでも見られます。 + +ここにチェックリストのサンプルがあります。 + +{{{ + #!ruby + Shoes.app do + stack do + flow { check; para "Frances Johnson" } + flow { check; para "Ignatius J. Reilly" } + flow { check; para "Winston Niles Rumfoord" } + end + end +}}} + +基本的にはチェック(check)を利用するための2つの方法があります。チェックにチェックがクリックされたときに呼ばれるブロックを取り付けます。そして/または、ボックスがチェックされているかどうか確認する`checked?`メソッドを利用できます。 + +では、上記の例に追加しましょう。 + +{{{ + #!ruby + Shoes.app do + @list = ['Frances Johnson', 'Ignatius J. Reilly', + 'Winston Niles Rumfoord'] + + stack do + @list.map! do |name| + flow { @c = check; para name } + [@c, name] + end + + button "What's been checked?" do + selected = @list.map { |c, name| name if c.checked? }.compact + alert("You selected: " + selected.join(', ')) + end + end + end +}}} + +そして、ボタンが押されたときに、`checked?`メソッドを利用して、それぞれのチェックはその状態を尋ねます。 + +下のボタンメソッドの一覧だけでなく、すべての要素が応答できる、[[Common]]メソッドの一覧も見てください。 + +=== checked?() » true or false === + +その箱がチェックされているかどうかを返します。そして、`true`の意味は"はい、この箱はチェックされています!"です。 + +=== checked = true or false === + +チェックボックスをマークしたりマークを外したりします。例えば、`checked = false`を利用して、箱のチェックを外します。 + +=== click() { |self| ... } » self === + +チェックボックスがクリックされたときに、その`click`ブロックが呼ばれます。このブロックは、クリックされたチェックボックスオブジェクトの`self`を渡します。 + +箱がチェックされるときとチェックを外すときのどちらもクリックが渡されます。 + +=== focus() » self === + +チェックボックスにフォーカスを移動します。そのチェックボックスはハイライトされ、ユーザがエンターキーを打てば、そのチェックボックスはチェックされた状態とチェックされていない状態の間をトグルします。 + +== EditBox == + +エディットボックス(Edit box)は、テキストを入力するための幅広い長方形の箱です。webでは、それらはテキストエリアと呼ばれます。それらは長い記述を入力するためのマルチラインエディットボックスです。エッセイでさえ書けます! !{:margin_left => 100}man-ele-editbox.png! + +スタイルを何も設定しなければ、エディットボックスは200ピクセルx108ピクセルのサイズです。特定のサイズに設定するために`:width`と`:height`のスタイルを利用することもできます。 + +{{{ + #!ruby + Shoes.app do + edit_box + edit_box :width => 100, :height => 100 + end +}}} + +([[Button]]や[[Check]]などの)他のコントロールはクリックイベントだけを持っていますが、[[EditLine]]やエディットボックス(EditBox)は`change`イベントも持っています。誰かがタイプしたり箱から削除したら`change`のブロックはいつでも呼ばれます。 + +{{{ + #!ruby + Shoes.app do + edit_box do |e| + @counter.text = e.text.size + end + @counter = strong("0") + para @counter, " characters" + end +}}} + +この例ではブロック内部で[[EditBox.text]]メソッドを利用していることにも注意してください。このメソッドは箱に対してタイプしたすべての文字の文字列をあなたに与えます。 + +エディットボックスの更なるメソッドは以下に一覧にしますが、すべての要素が応答できる、[[Common]]メソッドの一覧も見てください。 + +=== change() { |self| ... } » self === + +エディットボックスに文字が追加されたり取り除かれるたびに、`chenage`ブロックが呼ばれます。ブロックには変更されたエディットボックスのオブジェクトである`self`が与えられます。 + +=== focus() » self === + +エディットボックスにフォーカスを移動します。そのエディットボックスはハイライトされ、ユーザはエディットボックスにタイプできます。 + +=== text() » self === + +箱にタイプされた文字を文字列として返します。 + +=== text = a string === + +`a string`の文字をエディットボックスに代入します。 + +== EditLine == + +エディットライン(Edit line)は細長い、小さなテキストを入力する箱です。エディットボックスはマルチラインですが、エディットラインは1行です。これはエディットラインです。ちなみに水平です。 + +スタイルが設定されていないエディットラインは200ピクセルの幅と28ピクセルの高さです。これはおおよそです。プラットフォームによって高さは様々です。 + +{{{ + #!ruby + Shoes.app do + stack do + edit_line + edit_line :width => 400 + end + end +}}} + +`:width`と`:height`の両方のスタイルを設定することによりサイズを変更することができます。しかしながら、高さはフォントに合わせて調整されるため、一般的には`:width`だけのスタイルを設定します。(そして、現在のバージョンのShoesでは、エディットラインとエディットボックスフォントはどうやっても変更できません。) + +エディットラインにブロックが与えられたら、`change`イベントを受けとります。changeブロックを利用した例については[[EditBox]]のページを確認してください。実際には、そのエディットボックスはエディットラインとすべて同じメソッドを持ちます。すべての要素が応答できる、[[Common]]メソッドの一覧も見てください。 + +=== change() { |self| ... } » self === + +エディットラインに文字が追加されたり取り除かれるたびに、`chenage`ブロックが呼ばれます。ブロックには変更されたエディットラインのオブジェクトである`self`が与えられます。 + +=== focus() » self === + +エディットラインにフォーカスを移動します。そのエディットラインはハイライトされ、ユーザはエディットラインにタイプできます。 + +=== text() » self === + +箱にタイプされた文字を文字列として返します。 + +=== text = a string === + +`a string`の文字をエディットボックスに代入します。 + +== Image == + +画像(image)はPNG、JPEGまたはGIFフォーマットの画像ファイルです。Shoesは画像をリサイズまたはテキストとともにそれらをフローすることができます。!{:margin_left => 100}man-ele-image.png! + +画像を作成するために、スロット内部で`image`メソッドを利用します: + +{{{ + #!ruby + Shoes.app do + para "Nice, nice, very nice. Busy, busy, busy." + image "static/shoes-manual-apps.gif" + end +}}} + +Shoesに何らかの画像をロードしたとき、それはメモリにキャッシュされます。それは、同じファイルの画像の要素をたくさんロードした場合でも、それは実際には1回だけファイルをロードすることを意味します。 + +webのURLを直接利用することもできます。 + +{{{ + #!ruby + Shoes.app do + image "http://hacketyhack.heroku.com/images/logo.png" + end +}}} + +webから画像がロードされたとき、それはハードディスクドライブとメモリの両方にキャッシュされます。これは画像が変更されなければ再度ダウンロードをすることを防止します。(不思議に思う場合:正にブラウザが行うetagのようにShoesは変更時間の軌跡を保持します。) + +Shoesはバックグラウンドでシステムのスレッドを使ってリモートの画像もロードします。そのため、リモートの画像を利用することはRubyを妨げることはなく、またどんな強烈なグラフィカルな表示でも進み続けるでしょう。 + +=== full_height() » a number === + +画像全体のピクセルでの高さです。通常は、ピクセルでの画像の高さを知るために[[Common.height]]メソッドを利用できます。しかし画像がリサイズされていたりより大きいサイズなどにスタイルが設定されていた場合は、`height`は変更されたサイズを返します。 + +`full_height`メソッドは保存されたオリジナルファイルの画像の(ピクセルでの)高さを与えます。 + +=== full_width() » a number === + +画像全体のピクセルでの幅です。[[Common.width]]ではなくこのメソッドを使う理由の説明については[[Image.full_height]]メソッドを見てください。 + +=== path() » a string === + +画像のURLまたはファイル名です。 + +=== path = a string === + +ファイルまたはURLからロードして、画像を他のものに入れ替えます。 + +== ListBox == + +リストボックス(List box)(環境によって"コンボボックス(combo box)"または"ドロップダウンボックス(drop-down box)"または"セレクトボックス(select box)"とも呼ばれています。)は箱をクリックしたときドロップダウンしてオプションが一覧として表示されます。!{:margin_left => 100}man-ele-listbox.png! + +リストボックスは配列からオプションを取得します。配列(リスト)の文字列は、`:items`スタイルに渡されます。 + +{{{ + #!ruby + Shoes.app do + para "Choose a fruit:" + list_box :items => ["Grapes", "Pears", "Apricots"] + end +}}} + +そして、リストボックスの基本のサイズは200ピクセルの幅と28ピクセルの高さです。この長さは`width`スタイルを利用して調整することができます。 + +{{{ + #!ruby + Shoes.app do + para "Choose a fruit:" + list_box :items => ["Grapes", "Pears", "Apricots"], + :width => 120, :choose => "Apricots" do |list| + @fruit.text = list.text + end + + @fruit = para "No fruit selected" + end +}}} + +`:width`スタイルに続いて、この例ではもう1つの便利なオプションを利用します。`:choose`オプションは始めからハイライトされるべきアイテムをリストボックスに教えます。(箱が作成された後でアイテムをハイライトするには[[ListBox.choose]]メソッドもあります。) + +リストボックスは[[ListBox.change]]イベントも持っています。次の例では、リストボックスにブロックを取り付けました。いいですか、この`change`ブロックを見てください。このブロックは誰かが選択されたアイテムを変更するたびに呼ばれます。 + +これらは基本的なことです。すべての要素が持っているメソッドの完全な一覧である、[[Common]]メソッドのページを見てください。 + +=== change() { |self| ... } » self === + +誰かがリストボックスの新しいオプションをハイライトするたびに(例えば、アイテムをクリックすることによって)`change`ブロックは呼ばれます。ブロックには変更されたリストボックスのオブジェクトである`self`が与えられます。 + +=== choose(item: a string) » self === + +`item`として与えられた文字列と一致するリストボックス内のオプションを選択します + +=== focus() » self === + +リストボックスにフォーカスを移動します。そのリストはハイライトされ、ユーザが上や下の矢印キーを押した場合、リスト内の別のオプションが選択されます。 + +=== items() » an array of strings === + +リストボックスにオプションとして現在表示されている文字列の完全な一覧を返します。 + +=== items = an array of strings === + +リストボックスのオプションを新しい文字列の一覧で置き換えます。 + +=== text() » a string === + +現在リストボックス内でハイライトされて表示されているテキストを含む文字列です。何も選択されていないなら、`nil`が応答されます。 + +== Progress == + +プログレスバー(Progress bar)は活動がどこまで進んでいるかを表示します。一般的には、プログレスバーはパーセンテージで示されます。(0%から100%まで)Shoesは0.0から1.0の10進数を使って進行を考えます。!{:margin_left => 100}man-ele-progress.png! + +シンプルなプログレスバーは200ピクセルの幅ですが、長くするために(すべてのShoesの要素のように)`:width`スタイルは利用できません。 + +{{{ + Shoes.app do + stack :margin => 0.1 do + title "Progress example" + @p = progress :width => 1.0 + + animate do |i| + @p.fraction = (i % 100) / 100.0 + end + end + end +}}} + +プログレスバーを含む、すべての要素に備え付けられたメソッドの一覧については[[Common]]メソッドのページを見てください。 + +=== fraction() » a decimal number === + +どこまでプログレスバーが進んでいるかを指し示す、0.0から1.0の10進数の数を返します。 + +=== fraction = a decimal number === + +0.0から1.0の間の10進数の数で進行を設定します。 + +== Radio == + +ラジオボタン(Radio button)はクリック可能な円のグループです。それをマークするには円をクリックしてください。ラジオボタンは1度に1つだけマークできます。(1度に1つのオプションだけしか選択できないところは、リストボックスに似ています。)!{:margin_left => 100}man-ele-radio.png! + +それでは、リストボックスを利用すべきときと、ラジオボタンを利用すべきときをどのようにして決定しますか?そうですね、リストボックスはボックスをクリックしてドロップダウンを表示することなく1つのハイライトされたアイテムを表示します。しかし、ラジオボタンはどれがマークされているか気にすることなく、すべて表示されます。 + +{{{ + #!ruby + Shoes.app do + para "Among these films, which do you prefer?\n" + radio; para strong("The Taste of Tea"), " by Katsuhito Ishii\n" + radio; para strong("Kin-Dza-Dza"), " by Georgi Danelia\n" + radio; para strong("Children of Heaven"), " by Majid Majidi\n" + end +}}} + +それらは(たくさんの`para`とともに)同じスロット内で一緒にグループ化されているため、3つのラジオボタンから1度に1つだけが選択できます。 + +これらをそれら自身のスロットに移動したら、この例は壊れます。 + +{{{ + #!ruby + Shoes.app do + stack do + para "Among these films, which do you prefer?" + flow { radio; para "The Taste of Tea by Katsuhito Ishii" } + flow { radio; para "Kin-Dza-Dza by Georgi Danelia" } + flow { radio; para "Children of Heaven by Majid Majidi" } + end + end +}}} + +しかし、これは修正できます。 +違うスロットのラジオボタンを一緒にグループ化することができ、それらにすべて同じグループ名を与える必要があります。 + +ここでは`:films`グループにそれらすべてのラジオボタンをグループ化しました。 + +{{{ + #!ruby + Shoes.app do + stack do + para "Among these films, which do you prefer?" + flow do + radio :films + para "The Taste of Tea by Katsuhito Ishii" + end + flow do + radio :films + para "Kin-Dza-Dza by Georgi Danelia" + end + flow do + radio :films + para "Children of Heaven by Majid Majidi" + end + end + end +}}} + +下にあるそれらの一覧を越える更なるメソッドについては、[[Common]]メソッドのページを詳しく調べてください。それらのメソッドをすべてのラジオボタンで同様に利用できるからです。 + +=== checked?() » true or false === + +ラジオボタンがチェックされているかどうかを返します。 +そして、`true`の意味は"はい、チェックされています!"です。 + +=== checked = true or false === + +ラジオボタンをマークしたりマークを外したりします。例えば、`checked = false`を利用して、ラジオボタンをクリアします。 + +=== click() { |self| ... } » self === + +ラジオボタンがクリックされたとき、その`click`ブロックが呼ばれます。 +このブロックは、クリックされたラジオボタンを示すオブジェクトの`self`を渡します。 + +ラジオボタンをマークしたときとマークを外したときの両方で、クリックが送られます。 + +=== focus() » self === + +ラジオボタンのフォーカスを移動します。そのラジオボタンはハイライトされ、ユーザがエンターキーを打てば、そのラジオボタンはマークされた状態とマークされていない状態の間をトグルします。 + +== Shape == + +形状(shape)は通常は`oval`と`rect`のようにドローイングメソッドによって作成されるアウトラインパスです。!{:margin_left => 100}man-ele-shape.png! + +[[Common]]メソッドのページを見てください。形状はそれらすべてのメソッドに応答できます。 + +== TextBlock == + +テキストブロック(TextBlock)オブジェクトは単独の要素にとして形成されるテキストのグループを示します。例えば、太字のテキストを含むパラグラフです。リンクと太字のテキストを含むキャプションです。(そして、`caption`はテキストブロックのタイプです。しかしながら、`link`と`strong`はテキストクラスのタイプです。)!{:margin_left => 100}man-ele-textblock.png! + +テキストブロックのすべての種類はタイプは[[Element Element Creation]]ページで確認できます。 + + * [[Element.banner]], 48ピクセルのフォント。 + * [[Element.title]], 34ピクセルのフォント。 + * [[Element.subtitle]], 26ピクセルのフォント。 + * [[Element.tagline]], 18ピクセルのフォント。 + * [[Element.caption]], 14ピクセルのフォント。 + * [[Element.para]], 12ピクセルのフォント。 + * [[Element.inscription]], 10ピクセルのフォント。 + +=== contents() » an array of elements === + +ブロック内部の整形された文字列すべてのリストです。 + +=== replace(a string) === + +ブロック全体のテキストを`a string`の文字で置き換えます。 + +=== text() » a string === + +テキストボックスのすべての文字の文字列を返します。画面に表示されるかのように、すべてのスタイルまたはテキストクラスが取り除かれて実際の文字だけを返します。 + +=== text = a string === + +ブロック全体のテキストを`a string`の文字で置き換えます。 + +=== to_s() » a string === + +[[TextBlock.text]]のエイリアスです。テキストブロックのすべてのコンテンツをフラットにした文字列を返します。 + +== Timers == + +Shoesは3つのタイマー(timer)クラスを持っています:アニメーション(Animation)クラス、Everyクラスそしてタイマー(Timer)クラスです。アニメーションとEveryの両方は開始してから何度も何度も繰り替えします。タイマーは1度だけ実行されます。1回限りのタイマーです。 + +アニメーションとEveryは基本的には同じものです。違いはアニメーションは普通は1秒間にとてもたくさん実行されます。そしてEveryは数秒間ごとに実行されるか、まれにしか実行されません。 + +=== start() » self === + +どちらのタイプのタイマーもそれ自身で自動的に開始されるため、通常はこれは利用する必要がありません。しかし、[[Timers.stop]]でタイマーを止めて再開したい場合は、もちろん:これを利用してください! + +=== stop() » self === + +アニメーションまたはタイマーを中断します。1回限りのタイマーの場合はこれは既に実行されており、既に停止しているのでこのメソッドの効果はありません。 + +=== toggle() » self === + +アニメーションまたはタイマーが停止されていれば、開始します。既に実行されていれば、停止します。 + +== Video == + +Shoesは埋め込みのQuickTime、Flashビデオ(FLV)、DivX、Xvidそして様々な他の人気のあるビデオフォーマットをサポートしています。これはすべて2つの驚くべきオープンソースライブラリである、VideoLANとffmpegのおかげです。Shoes::Videoオブジェクトをセットアップするためにスロット上で`video`メソッドを利用してください。!{:margin_left => 100}man-ele-video.png! + +ビデオフォーマットに加えて、MP3、WAVとOgg Vorbisのような、いくつかのオーディオフォーマットもサポートされています。 + +ビデオサポートはShoesではオプションであり、いくつかのビルドではビデオをサポートしていません。例えば、PowerPCではビデオサポートは利用できません。Shoesをダウンロードしたときに、ビデオサポートが利用できないならプラットフォーム用のビルドのファイル名に`novideo`と記されています + +=== hide() » self === + +ビデオを非表示します。既に再生しているなら、ビデオは再生を続けます。これはビデオの表示をオフにするだけです。このメソッドの有力な使い方の1つは、MP3のようなオーディオファイルを再生するときに、ビデオの範囲を破壊することです。 + +=== length() » a number === + +ミリ秒でのビデオ全体の長さです。ビデオがまだロードされていない場合はnilを返します。 + +=== move(left, top) » self === + +(left, top)はビデオの左上の角であり、特定の座標にビデオを移動します。 + +=== pause() » self === + +ビデオが再生されていれば、一時停止します。 + +=== playing?() » true of false === + +ビデオを現在再生していれば、trueを返します。または、ビデオが一時停止されていたり停止されている場合はfalseです。 + +=== play() » self === + +既に再生いなければ、ビデオの再生を開始します。既に再生いるのなら、ビデオは始めから再度開始します。 + +=== position() » a decimal === + +(0.0)から(1.0)の間の10進数の(Floatの)数によるビデオの位置です。例えば、0.5のFloatの値はビデオの中間の位置を示します。 + +=== position = a decimal === + +Floatの値を利用してビデオの位置を設定します。25%の位置にビデオを移動するなら:`@video.position = 0.25`。 + +=== remove() » self === + +ビデオをスロットから取り除きます。なおビデオを停止します。 + +=== show() » self === + +`hide()`メソッドによって非表示にされていたなら、ビデオを表示します。 + +=== stop() » self === + +ビデオが再生されていれば、停止します。 + +=== time() » a number === + +ビデオのミリ秒での時間の位置です。そのため、そのビデオが10秒の再生時間なら、このメソッドは10000の数を返します + +=== time = a number === + +ミリ秒の時間でビデオの位置を設定します。 + +=== toggle() » self === + +ビデオの可視性をトグルします。ビデオが表示されていれば、`hide`が呼ばれます。そうでなければ、`show`が呼ばれます。 + += AndSoForth = + +その他の情報をこの場所で。 + +== Sample Apps == + +楽しみましょう。 + +{SAMPLES} + +== FAQ == + +お役立ち情報: + + * [[http://librelist.com/browser/shoes/ Shoes ML]] 気軽にメーリングリストへ参加下さい。 + * [[http://github.com/shoes/shoes/ 最新のソースコード]] は GitHubにあります。 + * [[http://wiki.github.com/shoes/shoes/recentbuilds/ 最新のビルド]] あなたのプラットフォームに合わせて選んで下さい。 + diff --git a/static/manual.css b/static/manual.css new file mode 100644 index 0000000..fa849a6 --- /dev/null +++ b/static/manual.css @@ -0,0 +1,167 @@ +body { + font-family: verdana, arial, sans-serif; + background: #DDD; + margin: 0; padding: 0; +} +a { + color: #378; + text-decoration: none; +} +a.hi { + color: #C30; + font-weight: bold; +} +a:hover { + text-decoration: underline; +} +#main { + width: 720px; + margin: 40px auto; +} +.sidebar { + position: fixed; + width: 120px; +} +#manual { + float: right; + width: 540px; + padding: 20px; + border: solid 1px #BBB; + background: #eee; + margin-bottom: 80px; +} +#manual li { + margin-bottom: 8px; +} +h1 { + font-weight: normal; + font-size: 42px; + margin-top: 0; +} +h2 { + font-weight: normal; + font-size: 12px; + color: #777; + margin: 0; +} +h4 { + font-weight: normal; + font-size: 32px; + margin-bottom: 0; +} +#manual img { + display: block; + margin: 0 auto; + padding: 10px; +} +div.method { + background: #333; + padding: 4px; + color: #CCC; +} +div.method a { + color: white; + text-decoration: none; + font-weight: bold; +} +.intro { + font-size: 140%; + border-bottom: solid 1px #BBB; +} +.sidebar ul { + list-style: none; + text-align: center; + margin: 0; padding: 10px; + font-size: 18px; +} +.sidebar ul.sub { + margin: 6px 0; padding: 0; + border-left: solid 1px #CCC; + border-right: solid 1px #CCC; +} +.sidebar ul.sub li { + margin: 0; padding: 0; + font-size: 14px; +} +.sidebar ul.sub a { + font-weight: normal; +} +.sidebar a { + color: #666; + font-weight: bold; + text-decoration: none; +} +.sidebar .prime { + display: block; + color: #BBB; + font-size: 38px; + margin-bottom: 20px; +} +.sidebar a:hover { + color: black; +} +div.color { + width: 31%; + float: left; + text-align: center; + padding: 6px; + font-size: 80%; +} +div.color h3, div.color p { + margin: 4px; +} +p.next { + clear: both; + border-top: solid 1px #BBB; + text-align: right; + font-size: 120%; + padding: 8px; +} + +/* code highlighting */ +pre { + background: white; + padding: 8px 0; + border: solid 1px #ddd; +} +pre .comment, .ruby .comment { + color: #696; +} pre .string, .ruby .string { + color: teal; +} +pre .constant, .ruby .constant { + font-weight: bold; +} +pre .symbol, .ruby .symbol { + color: green; +} +pre .keywords, .ruby .keywords { + color: #662; +} +pre .global, pre .ivar, .ruby .ivar { + color: #F60; +} +pre .brackets, .ruby .brackets { + color: #993; +} + +/* index pages */ +#index .hibox { + background: white; + border: solid 1px #ddd; +} +#index .hibox p { + font-size: 14px; + margin: 8px; +} +#index h1 { + margin: 0; +} +#index ul { + list-style: none; + font-size: 13px; +} +#index ul a.hi, +#index ul a.lo { + font-size: 18px; +} diff --git a/static/menu-corner1.png b/static/menu-corner1.png Binary files differnew file mode 100644 index 0000000..b81d33a --- /dev/null +++ b/static/menu-corner1.png diff --git a/static/menu-corner2.png b/static/menu-corner2.png Binary files differnew file mode 100644 index 0000000..f68e291 --- /dev/null +++ b/static/menu-corner2.png diff --git a/static/menu-gray.png b/static/menu-gray.png Binary files differnew file mode 100644 index 0000000..ca69e1a --- /dev/null +++ b/static/menu-gray.png diff --git a/static/menu-left.png b/static/menu-left.png Binary files differnew file mode 100644 index 0000000..3b616ae --- /dev/null +++ b/static/menu-left.png diff --git a/static/menu-right.png b/static/menu-right.png Binary files differnew file mode 100644 index 0000000..97629e8 --- /dev/null +++ b/static/menu-right.png diff --git a/static/menu-top.png b/static/menu-top.png Binary files differnew file mode 100644 index 0000000..2397dd3 --- /dev/null +++ b/static/menu-top.png diff --git a/static/shoes-dmg.jpg b/static/shoes-dmg.jpg Binary files differnew file mode 100644 index 0000000..12a52ca --- /dev/null +++ b/static/shoes-dmg.jpg diff --git a/static/shoes-icon-blue.png b/static/shoes-icon-blue.png Binary files differnew file mode 100644 index 0000000..d8aa9b7 --- /dev/null +++ b/static/shoes-icon-blue.png diff --git a/static/shoes-icon.png b/static/shoes-icon.png Binary files differnew file mode 100644 index 0000000..d533f7b --- /dev/null +++ b/static/shoes-icon.png diff --git a/static/shoes-manual-apps.gif b/static/shoes-manual-apps.gif Binary files differnew file mode 100644 index 0000000..3ff2e9e --- /dev/null +++ b/static/shoes-manual-apps.gif diff --git a/static/shoes_main_window.png b/static/shoes_main_window.png Binary files differnew file mode 100644 index 0000000..4efc3ee --- /dev/null +++ b/static/shoes_main_window.png diff --git a/static/stripe.png b/static/stripe.png Binary files differnew file mode 100644 index 0000000..6acb327 --- /dev/null +++ b/static/stripe.png diff --git a/static/stubs/blank.exe b/static/stubs/blank.exe Binary files differnew file mode 100644 index 0000000..73acc7c --- /dev/null +++ b/static/stubs/blank.exe diff --git a/static/stubs/blank.hfz b/static/stubs/blank.hfz Binary files differnew file mode 100644 index 0000000..0ee6d4f --- /dev/null +++ b/static/stubs/blank.hfz diff --git a/static/stubs/blank.run b/static/stubs/blank.run new file mode 100644 index 0000000..e2c4673 --- /dev/null +++ b/static/stubs/blank.run @@ -0,0 +1,375 @@ +#!/bin/sh +# This script was generated using Makeself 2.1.4 +FULLSIZE=#{FULLSIZE} +CRCsum="#{CRC}" +MD5="#{MD5}" +TMPROOT=${TMPDIR:=/tmp} + +label="#{LABEL}" +script="./sh-install" +scriptargs="" +targetdir="dist" +filesizes="#{SIZE}" +keep=n + +print_cmd_arg="" +if type printf > /dev/null; then + print_cmd="printf" +elif test -x /usr/ucb/echo; then + print_cmd="/usr/ucb/echo" +else + print_cmd="echo" +fi + +unset CDPATH + +MS_Printf() +{ + $print_cmd $print_cmd_arg "$1" +} + +MS_Progress() +{ + while read a; do + MS_Printf . + done +} + +MS_dd() +{ + blocks=`expr $3 / 1024` + bytes=`expr $3 % 1024` + dd if="$1" ibs=$2 skip=1 obs=1024 conv=sync 2> /dev/null | \ + { test $blocks -gt 0 && dd ibs=1024 obs=1024 count=$blocks ; \ + test $bytes -gt 0 && dd ibs=1 obs=1024 count=$bytes ; } 2> /dev/null +} + +MS_Help() +{ + cat << EOH >&2 +Makeself version 2.1.4 + 1) Getting help or info about $0 : + $0 --help Print this message + $0 --info Print embedded info : title, default target directory, embedded script ... + $0 --lsm Print embedded lsm entry (or no LSM) + $0 --list Print the list of files in the archive + $0 --check Checks integrity of the archive + + 2) Running $0 : + $0 [options] [--] [additional arguments to embedded script] + with following options (in that order) + --confirm Ask before running embedded script + --noexec Do not run embedded script + --keep Do not erase target directory after running + the embedded script + --nox11 Do not spawn an xterm + --nochown Do not give the extracted files to the current user + --target NewDirectory Extract in NewDirectory + --tar arg1 [arg2 ...] Access the contents of the archive through the tar command + -- Following arguments will be passed to the embedded script +EOH +} + +MS_Check() +{ + OLD_PATH=$PATH + PATH=${GUESS_MD5_PATH:-"$OLD_PATH:/bin:/usr/bin:/sbin:/usr/local/ssl/bin:/usr/local/bin:/opt/openssl/bin"} + MD5_PATH=`exec 2>&-; which md5sum || type md5sum | cut -c 11-` + MD5_PATH=${MD5_PATH:-`exec 2>&-; which md5 || type md5 | cut -c 8-`} + PATH=$OLD_PATH + MS_Printf "Verifying archive integrity..." + offset=`head -n 375 "$1" | wc -c | tr -d " "` + verb=$2 + i=1 + for s in $filesizes + do + crc=`echo $CRCsum | cut -d" " -f$i` + if test -x "$MD5_PATH"; then + md5=`echo $MD5 | cut -d" " -f$i` + if test $md5 = "00000000000000000000000000000000"; then + test x$verb = xy && echo " $1 does not contain an embedded MD5 checksum." >&2 + else + md5sum=`MS_dd "$1" $offset $s | "$MD5_PATH" | cut -b-32`; + if test "$md5sum" != "$md5"; then + echo "Error in MD5 checksums: $md5sum is different from $md5" >&2 + exit 2 + else + test x$verb = xy && MS_Printf " MD5 checksums are OK." >&2 + fi + crc="0000000000"; verb=n + fi + fi + if test $crc = "0000000000"; then + test x$verb = xy && echo " $1 does not contain a CRC checksum." >&2 + else + sum1=`MS_dd "$1" $offset $s | CMD_ENV=xpg4 cksum | awk '{print $1}'` + if test "$sum1" = "$crc"; then + test x$verb = xy && MS_Printf " CRC checksums are OK." >&2 + else + echo "Error in checksums: $sum1 is different from $crc" + exit 2; + fi + fi + i=`expr $i + 1` + offset=`expr $offset + $s` + done + echo " All good." +} + +UnTAR() +{ + tar $1vf - 2>&1 || { echo Extraction failed. > /dev/tty; kill -15 $$; } +} + +finish=true +xterm_loop= +nox11=n +copy=none +ownership=y +verbose=n + +initargs="$@" + +while true +do + case "$1" in + -h | --help) + MS_Help + exit 0 + ;; + --info) + echo Identification: "$label" + echo Target directory: "$targetdir" + echo Uncompressed size: #{RAWSIZE} KB + echo Compression: gzip + echo Date of packaging: #{TIME} + echo Built with Makeself version 2.1.4 on + echo Build command was: "/usr/bin/makeself \\ + \"dist\" \\ + \"pkg/#{NAME}.run\" \\ + \"#{LABEL}\" \\ + \"./sh-install\"" + if test x$script != x; then + echo Script run after extraction: + echo " " $script $scriptargs + fi + if test x"" = xcopy; then + echo "Archive will copy itself to a temporary location" + fi + if test x"n" = xy; then + echo "directory $targetdir is permanent" + else + echo "$targetdir will be removed after extraction" + fi + exit 0 + ;; + --dumpconf) + echo LABEL=\"$label\" + echo SCRIPT=\"$script\" + echo SCRIPTARGS=\"$scriptargs\" + echo archdirname=\"dist\" + echo KEEP=n + echo COMPRESS=gzip + echo filesizes=\"$filesizes\" + echo CRCsum=\"$CRCsum\" + echo MD5sum=\"$MD5\" + echo OLDUSIZE=#{RAWSIZE} + echo OLDSKIP=376 + exit 0 + ;; + --lsm) +cat << EOLSM +No LSM. +EOLSM + exit 0 + ;; + --list) + echo Target directory: $targetdir + offset=`head -n 375 "$0" | wc -c | tr -d " "` + for s in $filesizes + do + MS_dd "$0" $offset $s | eval "gzip -cd" | UnTAR t + offset=`expr $offset + $s` + done + exit 0 + ;; + --tar) + offset=`head -n 375 "$0" | wc -c | tr -d " "` + arg1="$2" + shift 2 + for s in $filesizes + do + MS_dd "$0" $offset $s | eval "gzip -cd" | tar "$arg1" - $* + offset=`expr $offset + $s` + done + exit 0 + ;; + --check) + MS_Check "$0" y + exit 0 + ;; + --confirm) + verbose=y + shift + ;; + --noexec) + script="" + shift + ;; + --keep) + keep=y + shift + ;; + --target) + keep=y + targetdir=${2:-.} + shift 2 + ;; + --nox11) + nox11=y + shift + ;; + --nochown) + ownership=n + shift + ;; + --xwin) + finish="echo Press Return to close this window...; read junk" + xterm_loop=1 + shift + ;; + --phase2) + copy=phase2 + shift + ;; + --) + shift + break ;; + -*) + echo Unrecognized flag : "$1" >&2 + MS_Help + exit 1 + ;; + *) + break ;; + esac +done + +case "$copy" in +copy) + tmpdir=$TMPROOT/makeself.$RANDOM.`date +"%y%m%d%H%M%S"`.$$ + mkdir "$tmpdir" || { + echo "Could not create temporary directory $tmpdir" >&2 + exit 1 + } + SCRIPT_COPY="$tmpdir/makeself" + echo "Copying to a temporary location..." >&2 + cp "$0" "$SCRIPT_COPY" + chmod +x "$SCRIPT_COPY" + cd "$TMPROOT" + exec "$SCRIPT_COPY" --phase2 + ;; +phase2) + finish="$finish ; rm -rf `dirname $0`" + ;; +esac + +if test "$nox11" = "n"; then + if tty -s; then # Do we have a terminal? + : + else + if test x"$DISPLAY" != x -a x"$xterm_loop" = x; then # No, but do we have X? + if xset q > /dev/null 2>&1; then # Check for valid DISPLAY variable + GUESS_XTERMS="xterm rxvt dtterm eterm Eterm kvt konsole aterm" + for a in $GUESS_XTERMS; do + if type $a >/dev/null 2>&1; then + XTERM=$a + break + fi + done + chmod a+x $0 || echo Please add execution rights on $0 + if test `echo "$0" | cut -c1` = "/"; then # Spawn a terminal! + exec $XTERM -title "$label" -e "$0" --xwin "$initargs" + else + exec $XTERM -title "$label" -e "./$0" --xwin "$initargs" + fi + fi + fi + fi +fi + +if test "$targetdir" = "."; then + tmpdir="." +else + if test "$keep" = y; then + echo "Creating directory $targetdir" >&2 + tmpdir="$targetdir" + dashp="-p" + else + tmpdir="$TMPROOT/selfgz$$$RANDOM" + dashp="" + fi + mkdir $dashp $tmpdir || { + echo 'Cannot create target directory' $tmpdir >&2 + echo 'You should try option --target OtherDirectory' >&2 + eval $finish + exit 1 + } +fi + +location="`pwd`" +if test x$SETUP_NOCHECK != x1; then + MS_Check "$0" +fi +offset=`head -n 375 "$0" | wc -c | tr -d " "` + +if test x"$verbose" = xy; then + MS_Printf "About to extract #{RAWSIZE} KB in $tmpdir ... Proceed ? [Y/n] " + read yn + if test x"$yn" = xn; then + eval $finish; exit 1 + fi +fi + +MS_Printf "Uncompressing $label" +res=3 +if test "$keep" = n; then + trap 'echo Signal caught, cleaning up >&2; cd $TMPROOT; /bin/rm -rf $tmpdir; eval $finish; exit 15' 1 2 3 15 +fi + +for s in $filesizes +do + if MS_dd "$0" $offset $s | eval "gzip -cd" | ( cd "$tmpdir"; UnTAR x ) | MS_Progress; then + if test x"$ownership" = xy; then + (PATH=/usr/xpg4/bin:$PATH; cd "$tmpdir"; chown -R `id -u` .; chgrp -R `id -g` .) + fi + else + echo + echo "Unable to decompress $0" >&2 + eval $finish; exit 1 + fi + offset=`expr $offset + $s` +done +echo + +cd "$tmpdir" +res=0 +if test x"$script" != x; then + if test x"$verbose" = xy; then + MS_Printf "OK to execute: $script $scriptargs $* ? [Y/n] " + read yn + if test x"$yn" = x -o x"$yn" = xy -o x"$yn" = xY; then + eval $script $scriptargs $*; res=$?; + fi + else + eval $script $scriptargs $*; res=$? + fi + if test $res -ne 0; then + test x"$verbose" = xy && echo "The program '$script' returned an error code ($res)" >&2 + fi +fi +if test "$keep" = n; then + cd $TMPROOT + /bin/rm -rf $tmpdir +fi +eval $finish; exit $res diff --git a/static/stubs/cocoa-install b/static/stubs/cocoa-install Binary files differnew file mode 100644 index 0000000..267821b --- /dev/null +++ b/static/stubs/cocoa-install diff --git a/static/stubs/sh-install b/static/stubs/sh-install new file mode 100644 index 0000000..098b3f0 --- /dev/null +++ b/static/stubs/sh-install @@ -0,0 +1,49 @@ +#!/bin/sh +shoes_host="http://shoes.heroku.com" +shoes_url="$shoes_host/pkg/policeman/linux/shoes-novideo" +this_dir=`pwd` + +shoes="$(which shoes)" +if [ -x "$this_dir/shoes" ] ; then + shoes="$this_dir/shoes" +fi +if [ -z "$shoes" ] ; then + shoes="$HOME/.shoes/shoes.run" +fi + +if [ ! -x "$shoes" ] ; then + echo "Downloading Shoes... " + + # First, try wget. + wget="wget -q -O -" + wdl="wget -q" + shoes_pkg="$($wget "$shoes_url" 2>/dev/null)" + + if [ -z "$shoes_pkg" ] ; then + # Then, try curl. + wget="curl -s" + wdl="curl -s -O" + shoes_pkg="$($wget "$shoes_url" 2>/dev/null)" + + if [ -z "$shoes_pkg" ] ; then + # Lastly, try bsd fetch. + wget="fetch -q -o -" + wdl="fetch -q" + shoes_pkg="$($wget "$shoes_url" 2>/dev/null)" + + if [ -z "$shoes_pkg" ] ; then + echo "sorry, couldn't find wget or curl." + exit 1; + fi + fi + fi + + #shoes_run="$shoes_host$shoes_pkg" + shoes_run="$shoes_pkg" + echo "Fetching $shoes_run..." + mkdir -p $HOME/.shoes + eval $wget "$shoes_run" > $shoes + chmod 755 $shoes +fi + +eval $shoes -- "$this_dir/#{SCRIPT}" diff --git a/static/stubs/shoes-stub-inject.exe b/static/stubs/shoes-stub-inject.exe Binary files differnew file mode 100644 index 0000000..afcb796 --- /dev/null +++ b/static/stubs/shoes-stub-inject.exe diff --git a/static/stubs/shoes-stub.exe b/static/stubs/shoes-stub.exe Binary files differnew file mode 100644 index 0000000..d803dc1 --- /dev/null +++ b/static/stubs/shoes-stub.exe diff --git a/static/tutor-back.png b/static/tutor-back.png Binary files differnew file mode 100644 index 0000000..0905c7a --- /dev/null +++ b/static/tutor-back.png |