README.md in glimmer-0.10.3 vs README.md in glimmer-0.10.4
- old
+ new
@@ -350,11 +350,11 @@
jgem install glimmer-dsl-swt
```
Or this command if you want a specific version:
```
-jgem install glimmer-dsl-swt -v 0.6.3
+jgem install glimmer-dsl-swt -v 0.6.5
```
`jgem` is JRuby's version of `gem` command.
RVM allows running `gem install` directly as an alias.
Otherwise, you may also run `jruby -S gem install ...`
@@ -368,11 +368,11 @@
### Option 2: Bundler
(Use for Manual App Creation)
Add the following to `Gemfile`:
```
-gem 'glimmer-dsl-swt', '~> 0.6.3'
+gem 'glimmer-dsl-swt', '~> 0.6.5'
```
And, then run:
```
jruby -S bundle install
@@ -384,10 +384,20 @@
## Glimmer Command
The `glimmer` command allows you to run, scaffold, package, and list Glimmer applications/gems.
+You can bring up usage instructions by running the `glimmer` command without arguments:
+
+```
+glimmer
+```
+
+On Mac and Linux, it additionally brings up a TUI (Text-based User Interface) for interactive navigation and execution of Glimmer tasks (courtesy of [rake-tui](https://github.com/AndyObtiva/rake-tui)).
+
+On Windows, it simply lists the available Glimmer tasks at the end (courtsey of [rake](https://github.com/ruby/rake)).
+
If you are new to Glimmer, you may read the Basic Usage section and skip the rest until you have gone through [Girb (Glimmer irb) Command](#girb-glimmer-irb-command), [Glimmer GUI DSL Syntax](#glimmer-gui-dsl-syntax), and [Samples](#samples).
### Basic Usage
```
@@ -413,47 +423,48 @@
### Advanced Usage
Below are the full usage instructions that come up when running `glimmer` without args.
```
+Glimmer (Ruby Desktop Development GUI Library) - JRuby Gem: glimmer-dsl-swt v0.6.5
+
Usage: glimmer [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
-Runs Glimmer applications/tasks.
+Runs Glimmer applications and tasks.
-Either a single task or one or more applications may be specified.
-
-When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
-
-Available tasks are below (you may also lookup by adding `require 'glimmer/rake_task'` in Rakefile and running rake -T):
-glimmer list:gems:customshell[query] # List Glimmer custom shell gems available at rubygems.org (query is optional) [alt: list:gems:cs]
-glimmer list:gems:customwidget[query] # List Glimmer custom widget gems available at rubygems.org (query is optional) [alt: list:gems:cw]
-glimmer list:gems:dsl[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
-glimmer package[type] # Package app for distribution (generating config, jar, and native files) (type is optional)
-glimmer package:clean # Clean by removing "dist" and "packages" directories
-glimmer package:config # Generate JAR config file
-glimmer package:jar # Generate JAR file
-glimmer package:lock_jars # Lock JARs
-glimmer package:native[type] # Generate Native files (DMG/PKG/APP on the Mac, MSI/EXE/IMAGE on Windows, RPM/DEB on Linux) (type is optional)
-glimmer scaffold[app_name] # Scaffold Glimmer application directory structure to build a new app
-glimmer scaffold:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under app/views (namespace is optional) [alt: scaffold:cs]
-glimmer scaffold:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cw]
-glimmer scaffold:gem:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under its own Ruby gem + app project (namespace is required) [alt: scaffold:gem:cs]
-glimmer scaffold:gem:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cw]
-
When applications are specified, they are run using JRuby,
automatically preloading the glimmer Ruby gem and SWT jar dependency.
-Optionally, extra Glimmer options, JRuby options and environment variables may be passed in.
+Optionally, extra Glimmer options, JRuby options, and/or environment variables may be passed in.
Glimmer options:
- "--quiet" : Does not announce file path of Glimmer application being launched
- "--debug" : Displays extra debugging information, passes "--debug" to JRuby, and enables debug logging
- "--log-level=VALUE" : Sets Glimmer's Ruby logger level ("ERROR" / "WARN" / "INFO" / "DEBUG"; default is none)
-Example: glimmer samples/hello_world.rb
+Tasks are run via rake. Some tasks take arguments in square brackets.
-This runs the Glimmer application samples/hello_world.rb
+Available tasks are below (if you do not see any, please add `require 'glimmer/rake_task'` to Rakefile and rerun or run rake -T):
+
+Select a Glimmer task to run: (Press ↑/↓ arrow to move, Enter to select and letters to filter)
+‣ glimmer list:gems:customshell[query] # List Glimmer custom shell gems available at rubygems.org (query is optional) [alt: list:gems:cs]
+ glimmer list:gems:customwidget[query] # List Glimmer custom widget gems available at rubygems.org (query is optional) [alt: list:gems:cw]
+ glimmer list:gems:dsl[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
+ glimmer package[type] # Package app for distribution (generating config, jar, and native files) (type is optional)
+ glimmer package:clean # Clean by removing "dist" and "packages" directories
+ glimmer package:config # Generate JAR config file
+ glimmer package:jar # Generate JAR file
+ glimmer package:lock_jars # Lock JARs
+ glimmer package:native[type] # Generate Native files
+ glimmer sample:code[name] # Outputs code for a Glimmer internal sample [included in gem] (name is required)
+ glimmer sample:list[query] # Lists Glimmer internal samples [included in gem]. Filters by query if specified (query is optional)
+ glimmer sample:run[name] # Runs a Glimmer internal sample [included in gem]. If no name is supplied, it runs all samples
+ glimmer scaffold[app_name] # Scaffold Glimmer application directory structure to build a new app
+ glimmer scaffold:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under app/views (namespace is optional) [alt: scaffold:cs]
+ glimmer scaffold:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cw]
+ glimmer scaffold:gem:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under its own Ruby gem + app project (namespace is required) [alt: scaffold:ge...
+ glimmer scaffold:gem:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cw]
```
Example (Glimmer/JRuby option specified):
```
glimmer --debug samples/hello/hello_world.rb
@@ -466,14 +477,341 @@
glimmer samples/hello/hello_world.rb samples/hello_tab.rb
```
Launches samples/hello/hello_world.rb and samples/hello_tab.rb at the same time, each in a separate JRuby thread.
+### Sample List/Run/Code
+
+#### Sample List
+
+You can list available Glimmer samples by running:
+
+```
+glimmer sample:list
+```
+
+This should output the following (providing the name of each sample, description, and command to run the sample and view its code):
+
+```
+$ glimmer sample:list
+
+ Glimmer Hello Samples (run all via: glimmer sample:run:hello):
+
+ Name Description Run
+
+ hello_browser Hello Browser glimmer sample:run[hello_browser]
+ hello_combo Hello Combo glimmer sample:run[hello_combo]
+ hello_computed Hello Computed glimmer sample:run[hello_computed]
+ hello_drag_and_drop Hello Drag And Drop glimmer sample:run[hello_drag_and_drop]
+ hello_list_multi_selection Hello List Multi Selection glimmer sample:run[hello_list_multi_selection]
+ hello_list_single_selection Hello List Single Selection glimmer sample:run[hello_list_single_selection]
+ hello_menu_bar Hello Menu Bar glimmer sample:run[hello_menu_bar]
+ hello_message_box Hello Message Box glimmer sample:run[hello_message_box]
+ hello_pop_up_context_menu Hello Pop Up Context Menu glimmer sample:run[hello_pop_up_context_menu]
+ hello_tab Hello Tab glimmer sample:run[hello_tab]
+ hello_world Hello World glimmer sample:run[hello_world]
+
+
+ Glimmer Elaborate Samples (run all via: glimmer sample:run:elaborate):
+
+ Name Description Run
+
+ contact_manager Contact Manager glimmer sample:run[contact_manager]
+ login Login glimmer sample:run[login]
+ tic_tac_toe Tic Tac Toe glimmer sample:run[tic_tac_toe]
+```
+
+#### Sample Run
+
+A sample may be run via `glimmer sample:run[name]`. This also outputs the sample code so that you could take a look at it and compare to the GUI that launches.
+
+If the sample name is left empty (e.g. `glimmer sample:run`), then all samples are run.
+
+Example:
+
+```
+glimmer sample:run[hello_tab]
+```
+
+This will run the hello_tab sample and output its code:
+
+```
+$ glimmer sample:run[hello_tab]
+
+# /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/hello/hello_tab.rb
+
+class HelloTab
+ include Glimmer
+ def launch
+ shell {
+ text "Hello, Tab!"
+ tab_folder {
+ tab_item {
+ text "English"
+ label {
+ text "Hello, World!"
+ }
+ }
+ tab_item {
+ text "French"
+ label {
+ text "Bonjour, Univers!"
+ }
+ }
+ }
+ }.open
+ end
+end
+
+HelloTab.new.launch
+
+# # #
+```
+
+![Hello Tab English](images/glimmer-hello-tab-english.png)
+
+#### Sample Code
+
+You may output any sample code via this command: `glimmer sample:code[name]`
+
+This is very similar to the sample run command, except the name is required.
+
+It will not only output the main sample file, but any required supporting files as well.
+
+Example:
+
+```
+$ glimmer sample:code[tic_tac_toe]
+
+# /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/elaborate/tic_tac_toe.rb
+
+require_relative "tic_tac_toe/board"
+
+class TicTacToe
+ include Glimmer
+
+ def initialize
+ @tic_tac_toe_board = Board.new
+ @shell = shell {
+ text "Tic-Tac-Toe"
+ minimum_size 150, 178
+ composite {
+ grid_layout 3, true
+ (1..3).each { |row|
+ (1..3).each { |column|
+ button {
+ layout_data :fill, :fill, true, true
+ text bind(@tic_tac_toe_board[row, column], :sign)
+ enabled bind(@tic_tac_toe_board[row, column], :empty)
+ font style: :bold, height: 20
+ on_widget_selected {
+ @tic_tac_toe_board.mark(row, column)
+ }
+ }
+ }
+ }
+ }
+ }
+ observe(@tic_tac_toe_board, :game_status) { |game_status|
+ display_win_message if game_status == Board::WIN
+ display_draw_message if game_status == Board::DRAW
+ }
+ end
+
+ def display_win_message
+ display_game_over_message("Player #{@tic_tac_toe_board.winning_sign} has won!")
+ end
+
+ def display_draw_message
+ display_game_over_message("Draw!")
+ end
+
+ def display_game_over_message(message_text)
+ message_box(@shell) {
+ text 'Game Over'
+ message message_text
+ }.open
+ @tic_tac_toe_board.reset
+ end
+
+ def open
+ @shell.open
+ end
+end
+
+TicTacToe.new.open
+
+# # #
+
+
+# /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/elaborate/tic_tac_toe/cell.rb
+
+class TicTacToe
+ class Cell
+ EMPTY = ""
+ attr_accessor :sign, :empty
+
+ def initialize
+ reset
+ end
+
+ def mark(sign)
+ self.sign = sign
+ end
+
+ def reset
+ self.sign = EMPTY
+ end
+
+ def sign=(sign_symbol)
+ @sign = sign_symbol
+ self.empty = sign == EMPTY
+ end
+
+ def marked
+ !empty
+ end
+ end
+end
+
+# # #
+
+
+# /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/elaborate/tic_tac_toe/board.rb
+
+require_relative 'cell'
+
+class TicTacToe
+ class Board
+ DRAW = :draw
+ IN_PROGRESS = :in_progress
+ WIN = :win
+ attr :winning_sign
+ attr_accessor :game_status
+
+ def initialize
+ @sign_state_machine = {nil => "X", "X" => "O", "O" => "X"}
+ build_grid
+ @winning_sign = Cell::EMPTY
+ @game_status = IN_PROGRESS
+ end
+
+ #row and column numbers are 1-based
+ def mark(row, column)
+ self[row, column].mark(current_sign)
+ game_over? #updates winning sign
+ end
+
+ def current_sign
+ @current_sign = @sign_state_machine[@current_sign]
+ end
+
+ def [](row, column)
+ @grid[row-1][column-1]
+ end
+
+ def game_over?
+ win? or draw?
+ end
+
+ def win?
+ win = (row_win? or column_win? or diagonal_win?)
+ self.game_status=WIN if win
+ win
+ end
+
+ def reset
+ (1..3).each do |row|
+ (1..3).each do |column|
+ self[row, column].reset
+ end
+ end
+ @winning_sign = Cell::EMPTY
+ @current_sign = nil
+ self.game_status=IN_PROGRESS
+ end
+
+ private
+
+ def build_grid
+ @grid = []
+ 3.times do |row_index| #0-based
+ @grid << []
+ 3.times { @grid[row_index] << Cell.new }
+ end
+ end
+
+ def row_win?
+ (1..3).each do |row|
+ if row_has_same_sign(row)
+ @winning_sign = self[row, 1].sign
+ return true
+ end
+ end
+ false
+ end
+
+ def column_win?
+ (1..3).each do |column|
+ if column_has_same_sign(column)
+ @winning_sign = self[1, column].sign
+ return true
+ end
+ end
+ false
+ end
+
+ #needs refactoring if we ever decide to make the board size dynamic
+ def diagonal_win?
+ if (self[1, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[3, 3].sign) and self[1, 1].marked
+ @winning_sign = self[1, 1].sign
+ return true
+ end
+ if (self[3, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[1, 3].sign) and self[3, 1].marked
+ @winning_sign = self[3, 1].sign
+ return true
+ end
+ false
+ end
+
+ def draw?
+ @board_full = true
+ 3.times do |x|
+ 3.times do |y|
+ @board_full = false if self[x, y].empty
+ end
+ end
+ self.game_status = DRAW if @board_full
+ @board_full
+ end
+
+ def row_has_same_sign(number)
+ row_sign = self[number, 1].sign
+ [2, 3].each do |column|
+ return false unless row_sign == (self[number, column].sign)
+ end
+ true if self[number, 1].marked
+ end
+
+ def column_has_same_sign(number)
+ column_sign = self[1, number].sign
+ [2, 3].each do |row|
+ return false unless column_sign == (self[row, number].sign)
+ end
+ true if self[1, number].marked
+ end
+
+ end
+end
+
+# # #
+```
+
### Scaffolding
Glimmer borrows from Rails the idea of Scaffolding, that is generating a structure for your app files that
-helps you get started just like true building scaffolding helps construction workers, civil engineers, and architects.
+helps you get started just like true buildinThis g scaffolding helps construction workers, civil engineers, and architects.
Glimmer scaffolding goes beyond just scaffolding the app files that Rails does. It also packages it and launches it,
getting you to a running and delivered state of an advanced "Hello, World!" Glimmer application right off the bat.
This should greatly facilitate building a new Glimmer app by helping you be productive and focus on app details while
@@ -539,27 +877,32 @@
Created greeter/bin/greeter
Created greeter/spec/spec_helper.rb
...
```
-Eventually, it will launch an advanced "Hello, World!" app window having the title of your application.
+Eventually, it will launch an advanced "Hello, World!" app window having the title of your application ("Greeter").
![Glimmer Scaffold App](images/glimmer-scaffolding-app.png)
It also comes with a boilerplate Preferences dialog.
![Glimmer Scaffold App Preferences](images/glimmer-scaffolding-app-preferences.png)
-Here is a Windows scaffolded app called Greeter:
+Here is the Windows version of the scaffolded "Greeter" app:
![Glimmer Scaffold App Windows](images/glimmer-scaffolding-app-windows.png)
-Here is the Windows version of the boilerplate Preferences dialog.
+And, here is the Windows version of the boilerplate Preferences dialog.
![Glimmer Scaffold App Windows Preferences](images/glimmer-scaffolding-app-windows-preferences.png)
+In order to run the app after making changes, you must run the `glimmer` command and pass it the generated script under the `bin` directory as an argument:
+```
+glimmer bin/greeter
+```
+
#### Custom Shell
To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
```
@@ -610,10 +953,14 @@
The Ruby gem name will follow the convention "glimmer-cs-customwidgetname-namespace" (the 'cs' is for Custom Shell).
Only official Glimmer gems created by the Glimmer project committers will have no namespace (e.g. [glimmer-cs-gladiator](https://rubygems.org/gems/glimmer-cs-gladiator) Ruby gem)
+Since custom shell gems are both an app and a gem, they provide two ways to run:
+- Run the `glimmer` command and pass it the generated script under the `bin` directory that matches the gem name (e.g. run `glimmer bin/glimmer-cs-calculator`)
+- Run the executable binary file that ships with the gem directly (without `glimmer`). It intentionally has a shorter name for convenience since it is meant to be used on the command line (not in a package), so you can leave out the `glimmer-cs-` prefix (e.g. run `bin/calculator` directly)
+
Examples:
- [glimmer-cs-gladiator](https://github.com/AndyObtiva/glimmer-cs-gladiator): Gladiator (Glimmer Editor)
- [glimmer-cs-calculator](https://github.com/AndyObtiva/glimmer-cs-calculator): Glimmer Calculator
@@ -737,11 +1084,11 @@
Name Gem Version Author Description
Css glimmer-dsl-css 0.2.0 AndyMaleh Glimmer DSL for CSS
Opal glimmer-dsl-opal 0.1.0 AndyMaleh Glimmer DSL for Opal
- Swt glimmer-dsl-swt 0.6.3 AndyMaleh Glimmer DSL for SWT
+ Swt glimmer-dsl-swt 0.6.5 AndyMaleh Glimmer DSL for SWT
Xml glimmer-dsl-xml 0.2.0 AndyMaleh Glimmer DSL for XML
```
### Packaging
@@ -2899,10 +3246,14 @@
result ||= method.end_with?('=')
result ||= ['finish_edit!', 'search', 'all_tree_items', 'depth_first_search'].include?(method) && is_a?(Glimmer::UI::CustomWidget) && body_root.respond_to?(method)
end
```
+### log_excluded_keywords
+
+This just tells Glimmer whether to log excluded keywords or not (at the debug level). It is off by default.
+
## Glimmer Style Guide
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
- Widget declarations may optionally have arguments and be followed by a block (to contain properties and content)
- Widget blocks are always declared with curly braces
@@ -3325,10 +3676,11 @@
- Ensure you have a Ruby script under `bin` directory that launches the application, preferably matching your project directory name (e.g. `bin/math_bowling`) :
```ruby
require_relative '../app/my_application.rb'
```
- Include Icon (Optional): If you'd like to include an icon for your app (.icns format on the Mac), place it under `package/macosx` matching the humanized application local directory name (e.g. 'Math Bowling.icns' [containing space] for MathBowling or math_bowling). You may generate your Mac icon easily using tools like Image2Icon (http://www.img2icnsapp.com/) or manually using the Mac terminal command `iconutil` (iconutil guide: https://applehelpwriter.com/tag/iconutil/)
+- Include DMG Background Icon (Optional): Simply place a .png file under `package/macosx/{HumanAppName}-background.png`
- Include Version (Optional): Create a `VERSION` file in your application and fill it your app version on one line (e.g. `1.1.0`)
- Include License (Optional): Create a `LICENSE.txt` file in your application and fill it up with your license (e.g. MIT). It will show up to people when installing your app. Note that, you may optionally also specify license type, but you'd have to do so manually via `-BlicenseType=MIT` shown in an [example below](#javapackager-extra-arguments).
- Extra args (Optional): You may optionally add the following to `Rakefile` to configure extra arguments for javapackager: `Glimmer::Packager.javapackager_extra_args = "..."` (Useful to avoid re-entering extra arguments on every run of rake task.). Read about them in [their section below](#javapackager-extra-arguments).
### javapackager Extra Arguments
@@ -3362,10 +3714,14 @@
JAVAPACKAGER_EXTRA_ARGS='-Bmac.CFBundleName="Math Bowling Game"' glimmer package
```
That overrides the default application display name.
+### Verbose Mode
+
+Pass `-v` to javapackager in `Glimmer::Package.javapackager_extra_args` or by running `glimmer package:native[type] -v` to learn more about further available customizations for the installer you are requesting to generate.
+
### Windows Application Packaging
Windows offers two options for setup packaging:
- `msi` (recommended): simpler packaging option. Requires [WiX Toolset](https://wixtoolset.org/) and [.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework). Simply run `glimmer package[msi]` (or `glimmer package:native[msi]` if it's not your first time) and it will give you more details on the pre-requisites you need to install (e.g. [WiX Toolset](https://wixtoolset.org/) and [.NET Framework 3.5 SP1](https://dotnet.microsoft.com/download/dotnet-framework/net35-sp1)).
- `exe`: more advanced packaging option. Requires [Inno Setup](https://jrsoftware.org/isinfo.php). Simply run `glimmer package[exe]` (or `glimmer package:native[exe]` if it's not your first time) and it will tell you what you need to install.
@@ -3448,9 +3804,10 @@
- [logging](https://github.com/TwP/logging): provides extra logging capabilities not available in Ruby Logger such as multi-threaded buffered asynchronous logging (to avoid affecting app performance) and support for multiple appenders such as stdout, syslog, and log files (the last one is needed on Windows where syslog is not supported)
- [nested_inherited_jruby_include_package](https://github.com/AndyObtiva/nested_inherited_jruby_include_package): makes included [SWT](https://www.eclipse.org/swt/)/[Java](https://www.java.com/en/) packages available to all classes/modules that mix in the Glimmer module without having to manually reimport
- [os](https://github.com/rdp/os): provides OS detection capabilities (e.g. `OS.mac?` or `OS.windows?`) to write cross-platform code inexpensively
- [puts_debuggerer](https://github.com/AndyObtiva/puts_debuggerer): helps in troubleshooting when adding `require 'pd'` and using the `pd` command instead of `puts` or `p` (also `#pd_inspect` or `#pdi` instead of `#inspect`)
- [rake](https://github.com/ruby/rake): used to implement and execute `glimmer` commands
+- [rake-tui](https://github.com/AndyObtiva/rake-tui): Rake Text-based User Interface. Allows navigating rake tasks with arrow keys and filtering task list by typing to quickly find an run a rake task.
- [super_module](https://github.com/AndyObtiva/super_module): used to cleanly write the Glimmer::UI:CustomWidget and Glimmer::UI::CustomShell modules
- [text-table](https://github.com/aptinio/text-table): renders textual data in a textual table for the command-line interface of Glimmer
- [warbler](https://github.com/jruby/warbler): converts a Glimmer app into a Java JAR file during packaging
## Glimmer Process