You [Gerald Bauer¹] have been permanently banned [for life] from participating in r/ruby (because of your writing off / outside of r/ruby). I do not see your participation adding anything to this [ruby] community.
-- Richard Schneeman (r/ruby mod and fanatic illiberal ultra leftie on a cancel culture mission)
¹: I know. Who cares? Who is this Gerald Bauer anyway. A random nobody for sure. It just happens that I am the admin among other things of Planet Ruby.
Case Studies of Code of Conduct "Cancel Culture" Out-Of-Control Power Abuse - Ruby - A Call for Tolerance On Ruby-Talk Results In Ban On Reddit RubyUpdate (August, 2022) - A Call for More Tolerance And Call For No-Ban Policy Results In Ban On Ruby-Talk (With No Reason Given)
> I just banned gerald.bauer@gmail.com. > > -- SHIBATA Hiroshi > >> THANK YOU >> >> -- Ryan Davis >> >> >> My full support to moderators. >> >> -- Xavier Noria >> >> My full support to moderators. >> >> -- Carlo E. Prelz >> >> That's fun. >> >> -- Alice
« Ruby Glimmer Days 2021, January 26th to January 29th - 4 Days of Ruby (Desktop) Gems
Written by Andy Maleh
Software Engineering Expert from Montreal, Quebec. Creator of Glimmer and Abstract Feature Branch. Speaker at RailsConf, RubyConf, AgileConf, EclipseCon, EclipseWorld. Master in Software Engineering, DePaul University, Chicago. Blogs at Code Mastery Takes Commitment To Bold Coding Adventures. Snowboarder and Drummer.
Glimmer DSL for LibUI is a prerequisite-free Ruby desktop development GUI (Graphical User Interface) library. LibUI is a thin Ruby wrapper around libui, a relatively new C GUI library that renders native desktop GUI controls on every platform (similar to SWT, but without the heavy weight of the Java Virtual Machine).
Glimmer DSL for LibUI is a good convenient choice for small simple applications due to having zero prerequisites beyond the dependencies included in the Ruby gem. Also, just like Glimmer DSL for Tk, its apps start instantly and have a small memory footprint. LibUI is a promising new GUI toolkit that might prove quite worthy in the future.
Mac | Windows | Linux |
---|---|---|
No need to pre-install any prerequisites. Just install the gem and have platform-independent native GUI that just works!
Glimmer DSL for LibUI aims to provide a DSL (Domain Specific Language) that enables more productive desktop development in Ruby with:
button
is automatically set as child of window
)LibUI.main
loop is started automatically when triggering show
on window
)The Glimmer GUI DSL follows these simple concepts in mapping from LibUI syntax:
window
or button
). Behind the scenes, they are represented by keyword methods that map to corresponding LibUI.new_keyword
methods receiving args (e.g. window('hello world', 300, 200, true)
).window {title 'hello world'; on_closing {puts 'Bye'}; button('greet')}
). Content block optionally receives one arg representing the control (e.g. button('greet') {|b| on_clicked { puts b.text}}
)title "hello world"
inside group
). Behind the scenes, properties correspond to LibUI.control_set_property
methods.on_
and receiving required block handler (e.g. on_clicked {puts 'clicked'}
inside button
). Optionally, the listener block can receive an arg representing the control (e.g. on_clicked {|btn| puts btn.text}
). Behind the scenes, listeners correspond to LibUI.control_on_event
methods.Example of an app written in Glimmer GUI DSL object-oriented declarative hierarchical syntax:
require 'glimmer-dsl-libui'
include Glimmer
window('hello world', 300, 200) {
button('Button') {
on_clicked do
msg_box('Information', 'You clicked the button')
end
}
on_closing do
puts 'Bye Bye'
end
}.show
Mac Screenshots
Windows Screenshots
Linux Screenshots
require 'glimmer-dsl-libui'
include Glimmer
window('hello world').show
Mac Screenshot:
Windows Screenshot:
Linux Screenshot:
This is an example that demonstrates the table
control in Glimmer DSL for LibUI.
The table
cell_rows
property declaration results in “implicit data-binding” between the table
control and Array
of Arrays
; a new Glimmer DSL for LibUI innovation that provides convenience automatic support for:
Array#delete
, Array#delete_at
, Array#delete_if
, or any filtering/deletion Array
method automatically deletes rows in actual table
controlArray#<<
, Array#push
, Array#prepend
, or any insertion/addition Array
method automatically inserts rows in actual table
controlArray#[]=
, Array#map!
, or any update Array
method automatically updates rows in actual table
controlrequire 'glimmer-dsl-libui'
include Glimmer
data = [
['task 1', 0],
['task 2', 15],
['task 3', 100],
['task 4', 75],
['task 5', -1],
]
window('Task Progress', 300, 200) {
vertical_box {
table {
text_column('Task')
progress_bar_column('Progress')
cell_rows data # implicit data-binding
}
button('Mark All As Done') {
stretchy false
on_clicked do
data.each_with_index do |row_data, row|
data[row][1] = 100 # automatically updates table due to implicit data-binding
end
end
}
}
}.show
Mac
Windows
Linux
Snake provides an example of building a desktop application test-first following the MVP (Model / View / Presenter) architectural pattern.
require 'glimmer-dsl-libui'
require 'glimmer/data_binding/observer'
require_relative 'snake/presenter/grid'
class Snake
CELL_SIZE = 15
SNAKE_MOVE_DELAY = 0.1
include Glimmer
def initialize
@game = Model::Game.new
@grid = Presenter::Grid.new(@game)
@game.start
create_gui
register_observers
end
def launch
@main_window.show
end
def register_observers
@game.height.times do |row|
@game.width.times do |column|
Glimmer::DataBinding::Observer.proc do |new_color|
@cell_grid[row][column].fill = new_color
end.observe(@grid.cells[row][column], :color)
end
end
Glimmer::DataBinding::Observer.proc do |game_over|
Glimmer::LibUI.queue_main do
if game_over
msg_box('Game Over!', "Score: #{@game.score}")
@game.start
end
end
end.observe(@game, :over)
Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
unless @game.over?
@game.snake.move
@main_window.title = "Glimmer Snake (Score: #{@game.score})"
end
end
end
def create_gui
@cell_grid = []
@main_window = window('Glimmer Snake', @game.width * CELL_SIZE, @game.height * CELL_SIZE) {
resizable false
vertical_box {
padded false
@game.height.times do |row|
@cell_grid << []
horizontal_box {
padded false
@game.width.times do |column|
area {
@cell_grid.last << path {
square(0, 0, CELL_SIZE)
fill Presenter::Cell::COLOR_CLEAR
}
on_key_up do |area_key_event|
orientation_and_key = [@game.snake.head.orientation, area_key_event[:ext_key]]
case orientation_and_key
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
@game.snake.turn_right
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
@game.snake.turn_left
else
# No Op
end
end
}
end
}
end
}
}
end
end
Snake.new.launch
Mac
Windows
Linux
Built with Ruby
(running Jekyll)
on 2023-01-25 18:05:39 +0000 in 0.371 seconds.
Hosted on GitHub Pages.
</> Source on GitHub.
(0) Dedicated to the public domain.