glimmer-dsl-libui 0.5.7 → 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5ccd1c22e43fbb8401dff62f07008895ad88522452f079112998d0e10f58d72
4
- data.tar.gz: 9820c416164d39189ca3d6cfc90076b566b68b3c5e50b293e85d97edd2d4d04b
3
+ metadata.gz: a21485d1722dad246e40058c46dc14b63103e93b1243db1c0ae49bc3b96f96ab
4
+ data.tar.gz: 390bac7628f29d016bfac073d926011d5fd91d10e7c23a95cae8b59c0bb4a55f
5
5
  SHA512:
6
- metadata.gz: 545d81430224a9e197ddc4cd15168af5a3cd5f0d24c20f405bb5db3bbe499e38fa0339697e254dd100d7a76aa733fc98f7c3d3f9a8f824dc45a0fc13c4651b24
7
- data.tar.gz: 41f91f675dab3a0ecc4004ddc6670db3770127e03dce01143c5be0996894abe9960ee7c6c2ef89166f88faaa6529e24a437821f6b59ce4f764a6c3f7407313cd
6
+ metadata.gz: 43aa1f65c47353b9ce340ff18264edaf6d9e6c09ee700919e3661b56d2bc8db00f1b31dd365b0a62ae7e39323dc07ba247bb0d06da24f51b01e477ceefa99a34
7
+ data.tar.gz: c58efb32bc59359ec84cc804eec113004191fa0031676f0af7224c91b8271fb4851939ea761ddbecbc9ca912065bd4616869c76c05c95306991e5e0c68c73bf3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.5.10
4
+
5
+ - Support nesting area mouse and keyboard listeners underneath shapes directly given the newly added support for the `include?(x, y)` method, which can be used to detect if a mouse or keyboard event fired for a specific shape
6
+ - examples/shape_coloring.rb
7
+
8
+ ## 0.5.9
9
+
10
+ - Upgrade to glimmer v2.7.3
11
+ - Upgrade to perfect-shape v1.0.3
12
+ - Support `path`/`figure`/shape `#contain?`, `#include?`, and `#bounding_box` methods via perfect-shape algorithms applying the path winding rule (aka `draw_fill_mode`)
13
+
14
+ ## 0.5.8
15
+
16
+ - Support `code_area` class-based custom control as a code-syntax-highlighted `area` control using the `rouge` gem
17
+ - `examples/basic_code_area.rb`
18
+ - Handle hex colors that have a 3-digit shorthand
19
+ - Stop annoying false negative logs when using `Glimmer::LibUI::CustomWindow`
20
+
3
21
  ## 0.5.7
4
22
 
5
23
  - Support Custom Window keywords (aka Applications) using `Glimmer::LibUI::CustomWindow` or alias of `Glimmer::LibUI::Application`
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.5.7
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.5.10
2
2
  ## Prerequisite-Free Ruby Desktop Development GUI Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -322,11 +322,11 @@ Mac | Windows | Linux
322
322
 
323
323
  [Check Out Many More Examples Over Here!](#examples)
324
324
 
325
- ![glimmer-dsl-libui-mac-snake.gif](images/glimmer-dsl-libui-mac-snake.gif)
325
+ [![glimmer-dsl-libui-mac-snake.gif](images/glimmer-dsl-libui-mac-snake.gif)](https://github.com/AndyObtiva/glimmer-dsl-libui#snake)
326
326
 
327
- ![glimmer-dsl-libui-mac-color-the-circles.gif](images/glimmer-dsl-libui-mac-color-the-circles.gif)
327
+ [![glimmer-dsl-libui-mac-color-the-circles.gif](images/glimmer-dsl-libui-mac-color-the-circles.gif)](https://github.com/AndyObtiva/glimmer-dsl-libui#color-the-circles)
328
328
 
329
- ![glimmer-dsl-libui-mac-tetris.gif](images/glimmer-dsl-libui-mac-tetris.gif)
329
+ [![glimmer-dsl-libui-mac-tetris.gif](images/glimmer-dsl-libui-mac-tetris.gif)](https://github.com/AndyObtiva/glimmer-dsl-libui#tetris)
330
330
 
331
331
  NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is 100% feature-complete with regards to covering the C [libui](https://github.com/andlabs/libui) library API and in beta mode (though the C [libui](https://github.com/andlabs/libui) is still mid-alpha, which is why [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) cannot be declared v1.0.0 yet). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. The more feedback and issues you report the better.
332
332
 
@@ -405,6 +405,7 @@ DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
405
405
  - [Basic Image](#basic-image)
406
406
  - [Basic Transform](#basic-transform)
407
407
  - [Basic Draw Text](#basic-draw-text)
408
+ - [Basic Code Area](#basic-code-area)
408
409
  - [Advanced Examples](#advanced-examples)
409
410
  - [Area Gallery](#area-gallery)
410
411
  - [Button Counter](#button-counter)
@@ -427,6 +428,7 @@ DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
427
428
  - [Tetris](#tetris)
428
429
  - [Tic Tac Toe](#tic-tac-toe)
429
430
  - [Timer](#timer)
431
+ - [Shape Coloring](#shape-coloring)
430
432
  - [Applications](#applications)
431
433
  - [Manga2PDF](#manga2pdf)
432
434
  - [Befunge98 GUI](#befunge98-gui)
@@ -577,7 +579,7 @@ gem install glimmer-dsl-libui
577
579
  Or install via Bundler `Gemfile`:
578
580
 
579
581
  ```ruby
580
- gem 'glimmer-dsl-libui', '~> 0.5.7'
582
+ gem 'glimmer-dsl-libui', '~> 0.5.10'
581
583
  ```
582
584
 
583
585
  Test that installation worked by running the [Meta-Example](#examples):
@@ -590,14 +592,40 @@ Mac | Windows | Linux
590
592
  ----|---------|------
591
593
  ![glimmer-dsl-libui-mac-meta-example.png](images/glimmer-dsl-libui-mac-meta-example.png) | ![glimmer-dsl-libui-windows-meta-example.png](images/glimmer-dsl-libui-windows-meta-example.png) | ![glimmer-dsl-libui-linux-meta-example.png](images/glimmer-dsl-libui-linux-meta-example.png)
592
594
 
593
- Now to use [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui), add `require 'glimmer-dsl-libui'` at the top, and then `include Glimmer` into the top-level main object for testing or into an actual class for serious usage.
595
+ Now to use [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui), add `require 'glimmer-dsl-libui'` at the top.
594
596
 
595
- Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
597
+ Afterwards, `include Glimmer` into the top-level main object for testing or into an actual class for serious usage.
598
+
599
+ Alternatively, `include Glimmer::LibUI::Application` to conveniently declare the GUI `body` and run via the `::launch` method (`Glimmer::LibUI::Application` is an alias for `Glimmer::LibUI::CustomWindow` since that is what it represents).
600
+
601
+ Example including `Glimmer::LibUI::Application` (you may copy/paste in [`girb`](#girb-glimmer-irb)):
602
+
603
+ ```ruby
604
+ require 'glimmer-dsl-libui'
605
+
606
+ class SomeGlimmerApp
607
+ include Glimmer::LibUI::Application
608
+
609
+ body {
610
+ window('hello world', 300, 200) {
611
+ button('Button') {
612
+ on_clicked do
613
+ puts 'Button Clicked'
614
+ end
615
+ }
616
+ }
617
+ }
618
+ end
619
+
620
+ SomeGlimmerApp.launch
621
+ ```
622
+
623
+ Example including `Glimmer` and manually implementing the `#launch` method (you may copy/paste in [`girb`](#girb-glimmer-irb)):
596
624
 
597
625
  ```ruby
598
626
  require 'glimmer-dsl-libui'
599
627
 
600
- class Application
628
+ class SomeGlimmerApp
601
629
  include Glimmer
602
630
 
603
631
  def launch
@@ -611,7 +639,23 @@ class Application
611
639
  end
612
640
  end
613
641
 
614
- Application.new.launch
642
+ SomeGlimmerApp.new.launch
643
+ ```
644
+
645
+ Example including `Glimmer` at the top-level scope just for some prototyping/demoing/testing (you may copy/paste in [`girb`](#girb-glimmer-irb)):
646
+
647
+ ```ruby
648
+ require 'glimmer-dsl-libui'
649
+
650
+ include Glimmer
651
+
652
+ window('hello world', 300, 200) {
653
+ button('Button') {
654
+ on_clicked do
655
+ puts 'Button Clicked'
656
+ end
657
+ }
658
+ }.show
615
659
  ```
616
660
 
617
661
  If you are new to [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui), check out [Girb](#girb-glimmer-irb) and [Examples](#examples) to quickly learn through copy/paste. You may refer to the [API](#api) later on once you have gotten your feet wet with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) and need more detailed reference information.
@@ -675,6 +719,7 @@ Keyword(Args) | Properties | Listeners
675
719
  `checkbox_text_column(name as String)` | `editable` (Boolean), `editable_checkbox` (Boolean), `editable_text` (Boolean) | None
676
720
  `checkbox_text_color_column(name as String)` | `editable` (Boolean), `editable_checkbox` (Boolean), `editable_text` (Boolean) | None
677
721
  `check_menu_item(text as String)` | `checked` (Boolean) | `on_clicked`
722
+ `code_area` | `language` (String) (default: `'ruby'`), `theme` (String) (default: `'glimmer'`), `code` (String) | None
678
723
  `combobox` | `items` (`Array` of `String`), `selected` (`Integer`), `selected_item` (`String`) | `on_selected`
679
724
  `color_button` | `color` (Array of `red` as `Float`, `green` as `Float`, `blue` as `Float`, `alpha` as `Float`), `red` as `Float`, `green` as `Float`, `blue` as `Float`, `alpha` as `Float` | `on_changed`
680
725
  `date_picker` | `time` (`Hash` of keys: `sec` as `Integer`, `min` as `Integer`, `hour` as `Integer`, `mday` as `Integer`, `mon` as `Integer`, `year` as `Integer`, `wday` as `Integer`, `yday` as `Integer`, `dst` as Boolean) | `on_changed`
@@ -1348,6 +1393,10 @@ In general, it is recommended to use declarative stable paths whenever feasible
1348
1393
 
1349
1394
  #### Area Listeners
1350
1395
 
1396
+ `area` supports a number of keyboard and mouse listeners to enable observing the control for user interaction to execute some logic.
1397
+
1398
+ The same listeners can be nested directly under `area` shapes like `rectangle` and `circle`, and [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) will automatically detect when the mouse lands within those shapes to constrain triggering the listeners by the shape regions.
1399
+
1351
1400
  `area` supported listeners are:
1352
1401
  - `on_key_event {|area_key_event| ...}`: general catch-all key event (recommend using fine-grained key events below instead)
1353
1402
  - `on_key_down {|area_key_event| ...}`
@@ -4987,6 +5036,62 @@ end
4987
5036
  BasicDrawText.new.launch
4988
5037
  ```
4989
5038
 
5039
+ #### Basic Code Area
5040
+
5041
+ [examples/basic_code_area.rb](examples/basic_code_area.rb)
5042
+
5043
+ Run with this command from the root of the project if you cloned the project:
5044
+
5045
+ ```
5046
+ ruby -r './lib/glimmer-dsl-libui' examples/basic_code_area.rb
5047
+ ```
5048
+
5049
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
5050
+
5051
+ ```
5052
+ ruby -r glimmer-dsl-libui -e "require 'examples/basic_code_area'"
5053
+ ```
5054
+
5055
+ Mac | Windows | Linux
5056
+ ----|---------|------
5057
+ ![glimmer-dsl-libui-mac-basic-code-area.png](images/glimmer-dsl-libui-mac-basic-code-area.png) | ![glimmer-dsl-libui-windows-basic-code-area.png](images/glimmer-dsl-libui-windows-basic-code-area.png) | ![glimmer-dsl-libui-linux-basic-code-area.png](images/glimmer-dsl-libui-linux-basic-code-area.png)
5058
+
5059
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
5060
+
5061
+ ```ruby
5062
+ require 'glimmer-dsl-libui'
5063
+
5064
+ class BasicCodeArea
5065
+ include Glimmer::LibUI::Application
5066
+
5067
+ before_body do
5068
+ @code = <<~CODE
5069
+ # Greets target with greeting
5070
+ def greet(greeting: 'Hello', target: 'World')
5071
+
5072
+ puts "\#{greeting}, \#{target}!"
5073
+ end
5074
+
5075
+ greet
5076
+ greet(target: 'Robert')
5077
+ greet(greeting: 'Aloha')
5078
+ greet(greeting: 'Aloha', target: 'Nancy')
5079
+ greet(greeting: 'Howdy', target: 'Doodle')
5080
+ CODE
5081
+ end
5082
+
5083
+ body {
5084
+ window('Basic Code Area', 400, 300) {
5085
+ margined true
5086
+
5087
+ code_area(language: 'ruby', code: @code)
5088
+ }
5089
+ }
5090
+ end
5091
+
5092
+ BasicCodeArea.launch
5093
+ ```
5094
+
4990
5095
  ### Advanced Examples
4991
5096
 
4992
5097
  #### Area Gallery
@@ -8967,8 +9072,6 @@ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version
8967
9072
  require 'glimmer-dsl-libui'
8968
9073
  require 'facets'
8969
9074
 
8970
- include Glimmer
8971
-
8972
9075
  Address = Struct.new(:street, :p_o_box, :city, :state, :zip_code)
8973
9076
 
8974
9077
  class FormField
@@ -9029,54 +9132,64 @@ class AddressView
9029
9132
  }
9030
9133
  end
9031
9134
 
9032
- address1 = Address.new('123 Main St', '23923', 'Denver', 'Colorado', '80014')
9033
- address2 = Address.new('2038 Park Ave', '83272', 'Boston', 'Massachusetts', '02101')
9034
-
9035
- window('Class-Based Custom Keyword') {
9036
- margined true
9135
+ class ClassBasedCustomControls
9136
+ include Glimmer::LibUI::Application # alias: Glimmer::LibUI::CustomWindow
9037
9137
 
9038
- horizontal_box {
9039
- vertical_box {
9040
- label('Address 1') {
9041
- stretchy false
9042
- }
9043
-
9044
- address_form(address: address1)
9045
-
9046
- horizontal_separator {
9047
- stretchy false
9048
- }
9049
-
9050
- label('Address 1 (Saved)') {
9051
- stretchy false
9052
- }
9053
-
9054
- address_view(address: address1)
9055
- }
9056
-
9057
- vertical_separator {
9058
- stretchy false
9059
- }
9060
-
9061
- vertical_box {
9062
- label('Address 2') {
9063
- stretchy false
9064
- }
9065
-
9066
- address_form(address: address2)
9067
-
9068
- horizontal_separator {
9069
- stretchy false
9070
- }
9138
+ before_body do
9139
+ @address1 = Address.new('123 Main St', '23923', 'Denver', 'Colorado', '80014')
9140
+ @address2 = Address.new('2038 Park Ave', '83272', 'Boston', 'Massachusetts', '02101')
9141
+ end
9142
+
9143
+ body {
9144
+ window('Class-Based Custom Keyword') {
9145
+ margined true
9071
9146
 
9072
- label('Address 2 (Saved)') {
9073
- stretchy false
9147
+ horizontal_box {
9148
+ vertical_box {
9149
+ label('Address 1') {
9150
+ stretchy false
9151
+ }
9152
+
9153
+ address_form(address: @address1)
9154
+
9155
+ horizontal_separator {
9156
+ stretchy false
9157
+ }
9158
+
9159
+ label('Address 1 (Saved)') {
9160
+ stretchy false
9161
+ }
9162
+
9163
+ address_view(address: @address1)
9164
+ }
9165
+
9166
+ vertical_separator {
9167
+ stretchy false
9168
+ }
9169
+
9170
+ vertical_box {
9171
+ label('Address 2') {
9172
+ stretchy false
9173
+ }
9174
+
9175
+ address_form(address: @address2)
9176
+
9177
+ horizontal_separator {
9178
+ stretchy false
9179
+ }
9180
+
9181
+ label('Address 2 (Saved)') {
9182
+ stretchy false
9183
+ }
9184
+
9185
+ address_view(address: @address2)
9186
+ }
9074
9187
  }
9075
-
9076
- address_view(address: address2)
9077
9188
  }
9078
9189
  }
9079
- }.show
9190
+ end
9191
+
9192
+ ClassBasedCustomControls.launch
9080
9193
  ```
9081
9194
 
9082
9195
  #### Area-Based Custom Controls
@@ -10908,6 +11021,125 @@ end
10908
11021
  Timer.new
10909
11022
  ```
10910
11023
 
11024
+ #### Shape Coloring
11025
+
11026
+ This example demonstrates being able to nest a listener within shapes directly, and [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) will automatically detect when the mouse lands inside a shape to notify listener.
11027
+
11028
+ [examples/shape_coloring.rb](examples/shape_coloring.rb)
11029
+
11030
+ Run with this command from the root of the project if you cloned the project:
11031
+
11032
+ ```
11033
+ ruby -r './lib/glimmer-dsl-libui' examples/shape_coloring.rb
11034
+ ```
11035
+
11036
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
11037
+
11038
+ ```
11039
+ ruby -r glimmer-dsl-libui -e "require 'examples/shape_coloring'"
11040
+ ```
11041
+
11042
+ ![glimmer-dsl-libui-mac-shape-coloring.png](images/glimmer-dsl-libui-mac-shape-coloring.png)
11043
+ ![glimmer-dsl-libui-mac-shape-coloring-color-dialog.png](images/glimmer-dsl-libui-mac-shape-coloring-color-dialog.png)
11044
+
11045
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
11046
+
11047
+ ```ruby
11048
+ require 'glimmer-dsl-libui'
11049
+
11050
+ class ShapeColoring
11051
+ include Glimmer::LibUI::Application
11052
+
11053
+ COLOR_SELECTION = Glimmer::LibUI.interpret_color(:red)
11054
+
11055
+ before_body {
11056
+ @shapes = []
11057
+ }
11058
+
11059
+ body {
11060
+ window('Shape Coloring', 200, 200) {
11061
+ margined false
11062
+
11063
+ grid {
11064
+ label("Click a shape to select and\nchange color via color button") {
11065
+ left 0
11066
+ top 0
11067
+ hexpand true
11068
+ halign :center
11069
+ vexpand false
11070
+ }
11071
+
11072
+ color_button { |cb|
11073
+ left 0
11074
+ top 1
11075
+ hexpand true
11076
+ vexpand false
11077
+
11078
+ on_changed do
11079
+ @selected_shape&.fill = cb.color
11080
+ end
11081
+ }
11082
+
11083
+ area {
11084
+ left 0
11085
+ top 2
11086
+ hexpand true
11087
+ vexpand true
11088
+
11089
+ rectangle(0, 0, 600, 400) { # background shape
11090
+ fill :white
11091
+ }
11092
+
11093
+ @shapes << colorable(:rectangle, 20, 20, 40, 20) { |shape|
11094
+ fill :lime
11095
+ }
11096
+
11097
+ @shapes << colorable(:square, 80, 20, 20) { |shape|
11098
+ fill :blue
11099
+ }
11100
+
11101
+ @shapes << colorable(:circle, 75, 70, 20, 20) { |shape|
11102
+ fill :green
11103
+ }
11104
+
11105
+ @shapes << colorable(:arc, 120, 70, 40, 0, 145) { |shape|
11106
+ fill :orange
11107
+ }
11108
+
11109
+ @shapes << colorable(:polygon, 120, 10, 120, 50, 150, 10, 150, 50) {
11110
+ fill :cyan
11111
+ }
11112
+
11113
+ @shapes << colorable(:polybezier, 20, 40,
11114
+ 30, 100, 50, 80, 80, 110,
11115
+ 40, 120, 20, 120, 30, 91) {
11116
+ fill :pink
11117
+ }
11118
+ }
11119
+ }
11120
+ }
11121
+ }
11122
+
11123
+ def colorable(shape_symbol, *args, &content)
11124
+ send(shape_symbol, *args) do |shape|
11125
+ on_mouse_up do |area_mouse_event|
11126
+ old_stroke = Glimmer::LibUI.interpret_color(shape.stroke).slice(:r, :g, :b)
11127
+ @shapes.each {|sh| sh.stroke = nil}
11128
+ @selected_shape = nil
11129
+ unless old_stroke == COLOR_SELECTION
11130
+ shape.stroke = COLOR_SELECTION.merge(thickness: 2)
11131
+ @selected_shape = shape
11132
+ end
11133
+ end
11134
+
11135
+ content.call(shape)
11136
+ end
11137
+ end
11138
+ end
11139
+
11140
+ ShapeColoring.launch
11141
+ ```
11142
+
10911
11143
  ## Applications
10912
11144
 
10913
11145
  Here are some applications built with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.7
1
+ 0.5.10
@@ -0,0 +1,31 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class BasicCodeArea
4
+ include Glimmer::LibUI::Application
5
+
6
+ before_body do
7
+ @code = <<~CODE
8
+ # Greets target with greeting
9
+ def greet(greeting: 'Hello', target: 'World')
10
+
11
+ puts "\#{greeting}, \#{target}!"
12
+ end
13
+
14
+ greet
15
+ greet(target: 'Robert')
16
+ greet(greeting: 'Aloha')
17
+ greet(greeting: 'Aloha', target: 'Nancy')
18
+ greet(greeting: 'Howdy', target: 'Doodle')
19
+ CODE
20
+ end
21
+
22
+ body {
23
+ window('Basic Code Area', 400, 300) {
24
+ margined true
25
+
26
+ code_area(language: 'ruby', code: @code)
27
+ }
28
+ }
29
+ end
30
+
31
+ BasicCodeArea.launch
@@ -0,0 +1,93 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class ShapeColoring
4
+ include Glimmer::LibUI::Application
5
+
6
+ COLOR_SELECTION = Glimmer::LibUI.interpret_color(:red)
7
+
8
+ before_body {
9
+ @shapes = []
10
+ }
11
+
12
+ body {
13
+ window('Shape Coloring', 200, 200) {
14
+ margined false
15
+
16
+ grid {
17
+ label("Click a shape to select and\nchange color via color button") {
18
+ left 0
19
+ top 0
20
+ hexpand true
21
+ halign :center
22
+ vexpand false
23
+ }
24
+
25
+ color_button { |cb|
26
+ left 0
27
+ top 1
28
+ hexpand true
29
+ vexpand false
30
+
31
+ on_changed do
32
+ @selected_shape&.fill = cb.color
33
+ end
34
+ }
35
+
36
+ area {
37
+ left 0
38
+ top 2
39
+ hexpand true
40
+ vexpand true
41
+
42
+ rectangle(0, 0, 600, 400) { # background shape
43
+ fill :white
44
+ }
45
+
46
+ @shapes << colorable(:rectangle, 20, 20, 40, 20) { |shape|
47
+ fill :lime
48
+ }
49
+
50
+ @shapes << colorable(:square, 80, 20, 20) { |shape|
51
+ fill :blue
52
+ }
53
+
54
+ @shapes << colorable(:circle, 75, 70, 20, 20) { |shape|
55
+ fill :green
56
+ }
57
+
58
+ @shapes << colorable(:arc, 120, 70, 40, 0, 145) { |shape|
59
+ fill :orange
60
+ }
61
+
62
+ @shapes << colorable(:polygon, 120, 10, 120, 50, 150, 10, 150, 50) {
63
+ fill :cyan
64
+ }
65
+
66
+ @shapes << colorable(:polybezier, 20, 40,
67
+ 30, 100, 50, 80, 80, 110,
68
+ 40, 120, 20, 120, 30, 91) {
69
+ fill :pink
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ def colorable(shape_symbol, *args, &content)
77
+ send(shape_symbol, *args) do |shape|
78
+ on_mouse_up do |area_mouse_event|
79
+ old_stroke = Glimmer::LibUI.interpret_color(shape.stroke).slice(:r, :g, :b)
80
+ @shapes.each {|sh| sh.stroke = nil}
81
+ @selected_shape = nil
82
+ unless old_stroke == COLOR_SELECTION
83
+ shape.stroke = COLOR_SELECTION.merge(thickness: 2)
84
+ @selected_shape = shape
85
+ end
86
+ end
87
+
88
+ content.call(shape)
89
+ end
90
+ end
91
+ end
92
+
93
+ ShapeColoring.launch
Binary file
@@ -27,7 +27,7 @@ module Glimmer
27
27
  module Libui
28
28
  class ListenerExpression < Expression
29
29
  def can_interpret?(parent, keyword, *args, &block)
30
- parent.is_a?(Glimmer::LibUI::ControlProxy) and
30
+ (parent.is_a?(Glimmer::LibUI::ControlProxy) or parent.is_a?(Glimmer::LibUI::Shape)) and
31
31
  block_given? and
32
32
  parent.can_handle_listener?(keyword)
33
33
  end
@@ -85,7 +85,7 @@ module Glimmer
85
85
  end
86
86
 
87
87
  def post_add_content
88
- unless parent_proxy.is_a?(Box)
88
+ if OS.linux? && parent_proxy.is_a?(WindowProxy)
89
89
  unless @content_added
90
90
  original_parent_proxy = @parent_proxy
91
91
  @vertical_box_parent_proxy = ControlProxy.create('vertical_box', parent_proxy, []) {} # block prevents calling post add content
@@ -23,6 +23,7 @@ require 'glimmer/libui/control_proxy'
23
23
  require 'glimmer/libui/control_proxy/area_proxy'
24
24
  require 'glimmer/libui/parent'
25
25
  require 'glimmer/libui/control_proxy/transformable'
26
+ require 'glimmer/libui/perfect_shaped'
26
27
 
27
28
  module Glimmer
28
29
  module LibUI
@@ -32,6 +33,7 @@ module Glimmer
32
33
  # Follows the Proxy Design Pattern
33
34
  class PathProxy < ControlProxy
34
35
  include Parent
36
+ include PerfectShaped
35
37
  prepend Transformable
36
38
 
37
39
  def initialize(keyword, parent, args, &block)
@@ -160,6 +162,30 @@ module Glimmer
160
162
  @parent_proxy&.request_auto_redraw
161
163
  end
162
164
 
165
+ def perfect_shape
166
+ perfect_shape_dependencies = [draw_fill_mode, children]
167
+ if perfect_shape_dependencies != @perfect_shape_dependencies
168
+ draw_fill_mode, children = @perfect_shape_dependencies = perfect_shape_dependencies
169
+ shapes = children.map(&:perfect_shape)
170
+ new_shapes = []
171
+ shapes.each do |shape|
172
+ if shape.is_a?(PerfectShape::Path)
173
+ new_shapes += shape.basic_shapes
174
+ else
175
+ new_shapes << shape
176
+ end
177
+ end
178
+ shapes = new_shapes
179
+ winding_rule = draw_fill_mode == :winding ? :wind_non_zero : :wind_even_odd
180
+ @perfect_shape = PerfectShape::Path.new(
181
+ shapes: shapes,
182
+ winding_rule: winding_rule,
183
+ line_to_complex_shapes: true
184
+ )
185
+ end
186
+ @perfect_shape
187
+ end
188
+
163
189
  private
164
190
 
165
191
  def build_control
@@ -401,4 +401,4 @@ module Glimmer
401
401
  end
402
402
  end
403
403
 
404
- Dir[File.expand_path('./control_proxy/*.rb', __dir__)].each {|f| require f}
404
+ Dir[File.expand_path("./#{File.basename(__FILE__, '.rb')}/*.rb", __dir__)].each {|f| require f}
@@ -0,0 +1,65 @@
1
+ class CodeArea
2
+ class << self
3
+ def languages
4
+ require 'rouge'
5
+ Rouge::Lexer.all.map {|lexer| lexer.tag}.sort
6
+ end
7
+
8
+ def lexers
9
+ require 'rouge'
10
+ Rouge::Lexer.all.sort_by(&:title)
11
+ end
12
+ end
13
+
14
+ include Glimmer::LibUI::CustomControl
15
+
16
+ REGEX_COLOR_HEX6 = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/
17
+
18
+ option :language, default: 'ruby'
19
+ option :theme, default: 'glimmer'
20
+ option :code
21
+
22
+ body {
23
+ area {
24
+ rectangle(0, 0, 8000, 8000) {
25
+ fill :white
26
+ }
27
+ text {
28
+ default_font family: OS.mac? ? 'Consolas' : 'Courier', size: 13, weight: :medium, italic: :normal, stretch: :normal
29
+
30
+ syntax_highlighting(code).each do |token|
31
+ style_data = Rouge::Theme.find(theme).new.style_for(token[:token_type])
32
+
33
+ string(token[:token_text]) {
34
+ color style_data[:fg] || :black
35
+ background style_data[:bg] || :white
36
+ }
37
+ end
38
+ }
39
+ }
40
+ }
41
+
42
+ def lexer
43
+ require 'rouge'
44
+ require 'glimmer-dsl-libui/ext/rouge/theme/glimmer'
45
+ # TODO Try to use Rouge::Lexer.find_fancy('guess', code) in the future to guess the language or otherwise detect it from file extension
46
+ @lexer ||= Rouge::Lexer.find_fancy(language)
47
+ @lexer ||= Rouge::Lexer.find_fancy('ruby') # default to Ruby if no lexer is found
48
+ end
49
+
50
+ def syntax_highlighting(text)
51
+ return [] if text.to_s.strip.empty?
52
+ @syntax_highlighting ||= {}
53
+ unless @syntax_highlighting.keys.include?(text)
54
+ lex = lexer.lex(text).to_a
55
+ text_size = 0
56
+ @syntax_highlighting[text] = lex.map do |pair|
57
+ {token_type: pair.first, token_text: pair.last}
58
+ end.each do |hash|
59
+ hash[:token_index] = text_size
60
+ text_size += hash[:token_text].size
61
+ end
62
+ end
63
+ @syntax_highlighting[text]
64
+ end
65
+ end
@@ -232,9 +232,10 @@ module Glimmer
232
232
  end
233
233
 
234
234
  def respond_to?(method_name, *args, &block)
235
- super or
236
- can_handle_listener?(method_name) or
237
- @body_root.respond_to?(method_name, *args, &block)
235
+ result = false
236
+ result ||= super
237
+ result ||= can_handle_listener?(method_name)
238
+ result ||= @body_root.respond_to?(method_name, *args, &block)
238
239
  end
239
240
 
240
241
  private
@@ -250,3 +251,5 @@ module Glimmer
250
251
  end
251
252
  end
252
253
  end
254
+
255
+ Dir[File.expand_path("./#{File.basename(__FILE__, '.rb')}/*.rb", __dir__)].each {|f| require f}
@@ -37,7 +37,11 @@ module Glimmer
37
37
  end
38
38
 
39
39
  def initialize(parent, *swt_constants, options, &content)
40
+ original_logger = Glimmer::Config.logger
41
+ require 'stringio'
42
+ Glimmer::Config.logger = Logger.new(StringIO.new)
40
43
  super
44
+ Glimmer::Config.logger = original_logger
41
45
  raise Glimmer::Error, 'Invalid custom window body root! Must be a window, another custom window, or a custom control with window as its body root!' unless body_root.is_a?(Glimmer::LibUI::ControlProxy::WindowProxy) || body_root.is_a?(Glimmer::LibUI::CustomWindow) || (body_root.is_a?(Glimmer::LibUI::CustomControl) && body_root.body_root.is_a?(Glimmer::LibUI::ControlProxy::WindowProxy))
42
46
  end
43
47
 
@@ -0,0 +1,46 @@
1
+ module Glimmer
2
+ module LibUI
3
+ # GUI View objects that can be represented by PerfectShape objects
4
+ module PerfectShaped
5
+ # Returns if shape contains point on the inside when outline is false (default)
6
+ # or if point is on the outline when outline is true
7
+ # distance_tolerance is used when outline is true to enable a fuzz factor in
8
+ # determining if a point lies on the outline (e.g. makes it easier to select
9
+ # a shape by mouse)
10
+ def contain?(*point, outline: false, distance_tolerance: 0)
11
+ perfect_shape&.contain?(*point, outline: outline, distance_tolerance: distance_tolerance)
12
+ end
13
+
14
+ # Returns if shape includes point on the inside when filled
15
+ # or if shape includes point on the outline when stroked
16
+ def include?(*point)
17
+ if fill.empty?
18
+ contain?(*point, outline: true, distance_tolerance: ((stroke[:thickness] || 1) - 1))
19
+ else
20
+ contain?(*point)
21
+ end
22
+ end
23
+
24
+ # Returns bounding box Array consisting of
25
+ # [minx, miny, width, height]
26
+ def bounding_box
27
+ perfect_shape_bounding_box = perfect_shape&.bounding_box
28
+ return if perfect_shape_bounding_box.nil?
29
+ [
30
+ perfect_shape_bounding_box.x,
31
+ perfect_shape_bounding_box.y,
32
+ perfect_shape_bounding_box.width,
33
+ perfect_shape_bounding_box.height,
34
+ ]
35
+ end
36
+
37
+ # Returns PerfectShape object matching this shape to enable
38
+ # executing computational geometry algorithms
39
+ #
40
+ # Including classes must implement
41
+ def perfect_shape
42
+ # No Op
43
+ end
44
+ end
45
+ end
46
+ end
@@ -29,7 +29,7 @@ module Glimmer
29
29
  class Figure < Shape
30
30
  parameters :x, :y
31
31
  parameter_defaults nil, nil
32
-
32
+
33
33
  def draw(area_draw_params)
34
34
  ::LibUI.draw_path_new_figure(path_proxy.libui, *@args) unless @args.compact.empty? # TODO if args empty then wait till there is an arc child and it starts the figure
35
35
  children.dup.each {|child| child.draw(area_draw_params)}
@@ -58,7 +58,12 @@ module Glimmer
58
58
  path_shapes = [[x, y]]
59
59
  path_shapes += children.map(&:perfect_shape)
60
60
  winding_rule = draw_fill_mode == :winding ? :wind_non_zero : :wind_even_odd
61
- @perfect_shape = PerfectShape::Path.new(closed: closed, winding_rule: winding_rule, shapes: path_shapes)
61
+ @perfect_shape = PerfectShape::Path.new(
62
+ closed: closed,
63
+ winding_rule: winding_rule,
64
+ shapes: path_shapes,
65
+ line_to_complex_shapes: true
66
+ )
62
67
  end
63
68
  @perfect_shape
64
69
  end
@@ -23,6 +23,7 @@ require 'glimmer/libui/parent'
23
23
  require 'glimmer/libui/control_proxy/area_proxy'
24
24
  require 'glimmer/libui/control_proxy/path_proxy'
25
25
  require 'glimmer/libui/data_bindable'
26
+ require 'glimmer/libui/perfect_shaped'
26
27
 
27
28
  module Glimmer
28
29
  module LibUI
@@ -65,6 +66,7 @@ module Glimmer
65
66
  end
66
67
 
67
68
  include Parent
69
+ include PerfectShaped
68
70
  include DataBindable
69
71
 
70
72
  attr_reader :parent, :args, :keyword, :block, :content_added
@@ -145,47 +147,17 @@ module Glimmer
145
147
  end
146
148
  alias transform= transform
147
149
  alias set_transform transform
148
-
149
- # Returns if shape contains point on the inside when outline is false (default)
150
- # or if point is on the outline when outline is true
151
- # distance_tolerance is used when outline is true to enable a fuzz factor in
152
- # determining if a point lies on the outline (e.g. makes it easier to select
153
- # a shape by mouse)
154
- def contain?(*point, outline: false, distance_tolerance: 0)
155
- perfect_shape&.contain?(*point, outline: outline, distance_tolerance: distance_tolerance)
156
- end
157
-
158
- # Returns if shape includes point on the inside when filled
159
- # or if shape includes point on the outline when stroked
160
- def include?(*point)
161
- if fill.empty?
162
- contain?(*point, outline: true, distance_tolerance: ((stroke[:thickness] || 1) - 1))
163
- else
164
- contain?(*point)
165
- end
166
- end
167
150
 
168
- # Returns bounding box Array consisting of
169
- # [minx, miny, width, height]
170
- def bounding_box
171
- perfect_shape_bounding_box = perfect_shape&.bounding_box
172
- return if perfect_shape_bounding_box.nil?
173
- [
174
- perfect_shape_bounding_box.x,
175
- perfect_shape_bounding_box.y,
176
- perfect_shape_bounding_box.width,
177
- perfect_shape_bounding_box.height,
178
- ]
151
+ def can_handle_listener?(listener_name)
152
+ area_proxy.can_handle_listener?(listener_name)
179
153
  end
180
154
 
181
- # Returns PerfectShape object matching this shape to enable
182
- # executing computational geometry algorithms
183
- #
184
- # Subclasses must implement
185
- def perfect_shape
186
- # No Op
155
+ def handle_listener(listener_name, &listener)
156
+ area_proxy.handle_listener(listener_name) do |event|
157
+ listener.call(event) if include?(event[:x], event[:y])
158
+ end
187
159
  end
188
-
160
+
189
161
  def respond_to?(method_name, *args, &block)
190
162
  self.class.parameters.include?(method_name.to_s.sub(/=$/, '').sub(/^set_/, '').to_sym) or
191
163
  super(method_name, true)
data/lib/glimmer/libui.rb CHANGED
@@ -80,11 +80,9 @@ module Glimmer
80
80
 
81
81
  def hex_to_rgb(value)
82
82
  if value.is_a?(String)
83
- value = "0x#{value[1..-1]}" if value.start_with?('#')
84
- if !value.start_with?('0x')
85
- value = value.chars.map {|char| [char, char]}.flatten.join if value.length == 3
86
- value = "0x#{value}"
87
- end
83
+ value = value[2..-1] if value.start_with?('0x')
84
+ value = value[1..-1] if value.start_with?('#')
85
+ value = value.chars.map {|char| [char, char]}.flatten.join if value.length == 3
88
86
  value = value.to_i(16)
89
87
  end
90
88
  if value.is_a?(Integer)
@@ -0,0 +1,29 @@
1
+ module Rouge
2
+ module Themes
3
+ # A port of the pastie style from Pygments.
4
+ # See https://bitbucket.org/birkenfeld/pygments-main/src/default/pygments/styles/pastie.py
5
+ class Glimmer < Github
6
+ name 'glimmer'
7
+ style Comment::Single, fg: [106,115,125], italic: true # Also, Comments
8
+ style Keyword::Pseudo, fg: [:dark_red]
9
+ style Keyword, fg: [:blue]
10
+ style Literal::String::Single, fg: [106,115,125] # Also, Comments
11
+ style Literal::String::Double, fg: [0,92,197]
12
+ style Literal::String::Escape, fg: [:red]
13
+ style Literal::Number::Integer, fg: [:blue]
14
+ style Literal::String::Interpol, fg: [:blue]
15
+ style Literal::String::Symbol, fg: [:dark_green]
16
+ style Literal::String, fg: [:dark_blue]
17
+ style Name::Builtin, fg: [215,58,73]
18
+ style Name::Class, fg: [3,47,98]
19
+ style Name::Namespace, fg: [3,47,98]
20
+ style Name::Constant, fg: [0,92,197]
21
+ style Name::Function, fg: [:blue]
22
+ style Name::Variable::Instance, fg: [227,98,9]
23
+ style Name, fg: [111,66,193] #purple
24
+ style Operator, fg: [:red]
25
+ style Punctuation, fg: [:blue]
26
+ style Text, fg: [75, 75, 75]
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.7
4
+ version: 0.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-24 00:00:00.000000000 Z
11
+ date: 2022-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.7.1
19
+ version: 2.7.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.7.1
26
+ version: 2.7.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: perfect-shape
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.1
33
+ version: 1.0.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.0.1
40
+ version: 1.0.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: super_module
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -128,6 +128,26 @@ dependencies:
128
128
  - - '='
129
129
  - !ruby/object:Gem::Version
130
130
  version: 0.0.11
131
+ - !ruby/object:Gem::Dependency
132
+ name: rouge
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: 3.26.0
138
+ - - "<"
139
+ - !ruby/object:Gem::Version
140
+ version: 4.0.0
141
+ type: :runtime
142
+ prerelease: false
143
+ version_requirements: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: 3.26.0
148
+ - - "<"
149
+ - !ruby/object:Gem::Version
150
+ version: 4.0.0
131
151
  - !ruby/object:Gem::Dependency
132
152
  name: juwelier
133
153
  requirement: !ruby/object:Gem::Requirement
@@ -265,6 +285,7 @@ files:
265
285
  - examples/basic_area3.rb
266
286
  - examples/basic_area4.rb
267
287
  - examples/basic_button.rb
288
+ - examples/basic_code_area.rb
268
289
  - examples/basic_draw_text.rb
269
290
  - examples/basic_draw_text2.rb
270
291
  - examples/basic_entry.rb
@@ -334,6 +355,7 @@ files:
334
355
  - examples/midi_player.rb
335
356
  - examples/midi_player2.rb
336
357
  - examples/midi_player3.rb
358
+ - examples/shape_coloring.rb
337
359
  - examples/simple_notepad.rb
338
360
  - examples/snake.rb
339
361
  - examples/snake/model/apple.rb
@@ -359,6 +381,7 @@ files:
359
381
  - icons/glimmer.png
360
382
  - lib/glimmer-dsl-libui.rb
361
383
  - lib/glimmer-dsl-libui/ext/glimmer.rb
384
+ - lib/glimmer-dsl-libui/ext/rouge/theme/glimmer.rb
362
385
  - lib/glimmer/dsl/libui/bind_expression.rb
363
386
  - lib/glimmer/dsl/libui/control_expression.rb
364
387
  - lib/glimmer/dsl/libui/custom_control_expression.rb
@@ -444,10 +467,12 @@ files:
444
467
  - lib/glimmer/libui/control_proxy/triple_column.rb
445
468
  - lib/glimmer/libui/control_proxy/window_proxy.rb
446
469
  - lib/glimmer/libui/custom_control.rb
470
+ - lib/glimmer/libui/custom_control/code_area.rb
447
471
  - lib/glimmer/libui/custom_window.rb
448
472
  - lib/glimmer/libui/data_bindable.rb
449
473
  - lib/glimmer/libui/image_path_renderer.rb
450
474
  - lib/glimmer/libui/parent.rb
475
+ - lib/glimmer/libui/perfect_shaped.rb
451
476
  - lib/glimmer/libui/shape.rb
452
477
  - lib/glimmer/libui/shape/arc.rb
453
478
  - lib/glimmer/libui/shape/bezier.rb