glimmer-dsl-libui 0.5.8 → 0.5.11

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: d99fb74f5b4aa47cf07f00cf6afb426a66cbac0947d1e854c859703b9158d635
4
- data.tar.gz: 75a27219914e19011e47051b60312e11ac83980d98e18fcb387ea84bfbfb6dd5
3
+ metadata.gz: edec94cbcdfb5f8766a7b04c6c19719a8525d971349db5c3f2989b762cee2c56
4
+ data.tar.gz: 60706b17b64dd6660a14dc46e31ec16039daa3074e4f3e3561061d20898271ff
5
5
  SHA512:
6
- metadata.gz: bf483f831272a8d2443a1b932ab2e25043377d3c349a6dbd1810055ed87b6b8409b78e74e7e8d938dda8945108258dd692626dcc2f859d8309066c7e6c1ef058
7
- data.tar.gz: 94d01b95cab06dbab277fdd1e2478b5f49c635e07c0702fb51e3726594de6a76a55d3d15185abeed8064ab12cec9bd16bbee5f1aa131ebae9c6e22d5401c4584
6
+ metadata.gz: e08e7c05b971f6ff16213dbdf14f8809fe45aa8f8d8b2ba563468eaf2eb14867a6cce4552fe4ae897e2a475b19b59f8179eb18864f15981db3c55bbe2dddd724
7
+ data.tar.gz: a96f5e238962f5998385046af93b2b5f101612e3626be7261de9373f7e106dd03fab044afe9bb2b5a7130f2b6e90ce900551a9ad209cddeb1fd2df59065edfca
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.5.11
4
+
5
+ - Upgrade to perfect-shape 1.0.4
6
+ - Update examples/shape_coloring.rb with basic drag and drop support
7
+ - Support `#move_by(x_delta, y_delta)` (alias `translate`) method on all shapes and `path` (e.g. useful in drag and drop)
8
+ - Support `#move(x, y)` method on all shapes and `path` to move to x,y coordinate directly
9
+ - Support `#min_x` minimum x coordinate of shape/`path` (of top-left corner)
10
+ - Support `#min_y` minimum y coordinate of shape/`path` (of top-left corner)
11
+ - Support `#max_x` maximum x coordinate of shape/`path` (of bottom-right corner)
12
+ - Support `#max_y` maximum y coordinate of shape/`path` (of bottom-right corner)
13
+ - Support `#center_point` (`Array` of x,y) center point of shape/`path`
14
+ - Support `#center_x` center x coordinate of shape/`path`
15
+ - Support `#center_y` center y coordinate of shape/`path`
16
+
17
+ ## 0.5.10
18
+
19
+ - Support nesting area mouse listeners underneath shapes directly given the newly added support for the `include?(x, y)` method, which can be used to detect if a mouse event fired for a specific shape
20
+ - examples/shape_coloring.rb
21
+
22
+ ## 0.5.9
23
+
24
+ - Upgrade to glimmer v2.7.3
25
+ - Upgrade to perfect-shape v1.0.3
26
+ - Support `path`/`figure`/shape `#contain?`, `#include?`, and `#bounding_box` methods via perfect-shape algorithms applying the path winding rule (aka `draw_fill_mode`)
27
+
3
28
  ## 0.5.8
4
29
 
5
30
  - Support `code_area` class-based custom control as a code-syntax-highlighted `area` control using the `rouge` gem
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.8
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.11
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
 
@@ -428,6 +428,7 @@ DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
428
428
  - [Tetris](#tetris)
429
429
  - [Tic Tac Toe](#tic-tac-toe)
430
430
  - [Timer](#timer)
431
+ - [Shape Coloring](#shape-coloring)
431
432
  - [Applications](#applications)
432
433
  - [Manga2PDF](#manga2pdf)
433
434
  - [Befunge98 GUI](#befunge98-gui)
@@ -578,7 +579,7 @@ gem install glimmer-dsl-libui
578
579
  Or install via Bundler `Gemfile`:
579
580
 
580
581
  ```ruby
581
- gem 'glimmer-dsl-libui', '~> 0.5.8'
582
+ gem 'glimmer-dsl-libui', '~> 0.5.11'
582
583
  ```
583
584
 
584
585
  Test that installation worked by running the [Meta-Example](#examples):
@@ -1087,13 +1088,22 @@ Mac | Windows | Linux
1087
1088
  ----|---------|------
1088
1089
  ![glimmer-dsl-libui-mac-area-gallery.png](images/glimmer-dsl-libui-mac-area-gallery.png) | ![glimmer-dsl-libui-windows-area-gallery.png](images/glimmer-dsl-libui-windows-area-gallery.png) | ![glimmer-dsl-libui-linux-area-gallery.png](images/glimmer-dsl-libui-linux-area-gallery.png)
1089
1090
 
1090
- ##### Shape Methods
1091
+ ##### Area Path Shape Methods
1091
1092
 
1092
1093
  - `::parameters`: returns parameters of a shape class
1093
1094
  - `#bounding_box`: returns `Array` containing `[min_x, min_y, width, height]`
1094
1095
  - `#contain?(*point, outline: false, distance_tolerance: 0)`: Returns if point (`[x, y]` `Array` or args) is inside the shape when `outline` is `false` or on the outline when `outline` is `true`. `distance_tolerance` is used when `outline` is `true` as a fuzz factor for declaring a point on the outline of the shape (e.g. helps users select a shape from its outline more easily).
1095
1096
  - `#include?(*point)`: Returns if point (`[x, y]` `Array` or args) is inside the shape when filled (having `fill` value) or on the outline when stroked (not having `fill` value yet `stroke` value only)
1096
1097
  - `#perfect_shape`: returns [PerfectShape](https://github.com/AndyObtiva/perfect-shape) object matching the [libui](https://github.com/andlabs/libui) shape.
1098
+ - `#move_by(x_delta, y_delta)` (alias: `translate`): moves (translates) shape by x,y delta
1099
+ - `#move(x, y)`: moves (translates) shape to x,y coordinates (in the top-left x,y corner of the shape)
1100
+ - `#min_x`: minimum x coordinate of shape (of top-left corner)
1101
+ - `#min_y`: minimum y coordinate of shape (of top-left corner)
1102
+ - `#max_x`: maximum x coordinate of shape (of bottom-right corner)
1103
+ - `#max_y`: maximum y coordinate of shape (of bottom-right corner)
1104
+ - `#center_point` (`Array` of x,y): center point of shape
1105
+ - `#center_x`: center x coordinate of shape
1106
+ - `#center_y`: center y coordinate of shape
1097
1107
 
1098
1108
  #### Area Text
1099
1109
 
@@ -1392,6 +1402,10 @@ In general, it is recommended to use declarative stable paths whenever feasible
1392
1402
 
1393
1403
  #### Area Listeners
1394
1404
 
1405
+ `area` supports a number of keyboard and mouse listeners to enable observing the control for user interaction to execute some logic.
1406
+
1407
+ 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.
1408
+
1395
1409
  `area` supported listeners are:
1396
1410
  - `on_key_event {|area_key_event| ...}`: general catch-all key event (recommend using fine-grained key events below instead)
1397
1411
  - `on_key_down {|area_key_event| ...}`
@@ -11016,6 +11030,176 @@ end
11016
11030
  Timer.new
11017
11031
  ```
11018
11032
 
11033
+ #### Shape Coloring
11034
+
11035
+ This example demonstrates being able to nest listeners within shapes directly, and [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) will automatically detect when the mouse lands inside the shapes to notify listeners.
11036
+
11037
+ This example also demonstrates very basic drag and drop support, implemented manually with shape listeners.
11038
+
11039
+ [examples/shape_coloring.rb](examples/shape_coloring.rb)
11040
+
11041
+ Run with this command from the root of the project if you cloned the project:
11042
+
11043
+ ```
11044
+ ruby -r './lib/glimmer-dsl-libui' examples/shape_coloring.rb
11045
+ ```
11046
+
11047
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
11048
+
11049
+ ```
11050
+ ruby -r glimmer-dsl-libui -e "require 'examples/shape_coloring'"
11051
+ ```
11052
+
11053
+ Shape Coloring Example
11054
+
11055
+ ![glimmer-dsl-libui-mac-shape-coloring.png](images/glimmer-dsl-libui-mac-shape-coloring.png)
11056
+
11057
+ ![glimmer-dsl-libui-mac-shape-coloring-drag-and-drop.png](images/glimmer-dsl-libui-mac-shape-coloring-drag-and-drop.png)
11058
+
11059
+ ![glimmer-dsl-libui-mac-shape-coloring-color-dialog.png](images/glimmer-dsl-libui-mac-shape-coloring-color-dialog.png)
11060
+
11061
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
11062
+
11063
+ ```ruby
11064
+ require 'glimmer-dsl-libui'
11065
+
11066
+ class ShapeColoring
11067
+ include Glimmer::LibUI::Application
11068
+
11069
+ COLOR_SELECTION = Glimmer::LibUI.interpret_color(:red)
11070
+
11071
+ before_body {
11072
+ @shapes = []
11073
+ }
11074
+
11075
+ body {
11076
+ window('Shape Coloring', 200, 220) {
11077
+ margined false
11078
+
11079
+ grid {
11080
+ label("Drag & drop shapes to move or\nclick a shape to select and\nchange color via color button") {
11081
+ left 0
11082
+ top 0
11083
+ hexpand true
11084
+ halign :center
11085
+ vexpand false
11086
+ }
11087
+
11088
+ color_button { |cb|
11089
+ left 0
11090
+ top 1
11091
+ hexpand true
11092
+ vexpand false
11093
+
11094
+ on_changed do
11095
+ @selected_shape&.fill = cb.color
11096
+ end
11097
+ }
11098
+
11099
+ area {
11100
+ left 0
11101
+ top 2
11102
+ hexpand true
11103
+ vexpand true
11104
+
11105
+ rectangle(0, 0, 600, 400) { # background shape
11106
+ fill :white
11107
+ }
11108
+
11109
+ @shapes << colorable(:rectangle, 20, 20, 40, 20) {
11110
+ fill :lime
11111
+ }
11112
+
11113
+ @shapes << colorable(:square, 80, 20, 20) {
11114
+ fill :blue
11115
+ }
11116
+
11117
+ @shapes << colorable(:circle, 75, 70, 20) {
11118
+ fill :green
11119
+ }
11120
+
11121
+ @shapes << colorable(:arc, 120, 70, 40, 0, 145) {
11122
+ fill :orange
11123
+ }
11124
+
11125
+ @shapes << colorable(:polygon, 120, 10, 120, 50, 150, 10, 150, 50) {
11126
+ fill :cyan
11127
+ }
11128
+
11129
+ @shapes << colorable(:polybezier, 20, 40,
11130
+ 30, 100, 50, 80, 80, 110,
11131
+ 40, 120, 20, 120, 30, 91) {
11132
+ fill :pink
11133
+ }
11134
+
11135
+ on_mouse_dragged do |area_mouse_event|
11136
+ mouse_dragged(area_mouse_event)
11137
+ end
11138
+
11139
+ on_mouse_dropped do |area_mouse_event|
11140
+ mouse_dropped(area_mouse_event)
11141
+ end
11142
+ }
11143
+ }
11144
+ }
11145
+ }
11146
+
11147
+ def colorable(shape_symbol, *args, &content)
11148
+ send(shape_symbol, *args) do |shape|
11149
+ on_mouse_up do |area_mouse_event|
11150
+ unless @dragged_shape
11151
+ old_stroke = Glimmer::LibUI.interpret_color(shape.stroke).slice(:r, :g, :b)
11152
+ @shapes.each {|sh| sh.stroke = nil}
11153
+ @selected_shape = nil
11154
+ unless old_stroke == COLOR_SELECTION
11155
+ shape.stroke = COLOR_SELECTION.merge(thickness: 2)
11156
+ @selected_shape = shape
11157
+ end
11158
+ end
11159
+ end
11160
+
11161
+ on_mouse_drag_started do |area_mouse_event|
11162
+ mouse_drag_started(shape, area_mouse_event)
11163
+ end
11164
+
11165
+ on_mouse_dragged do |area_mouse_event|
11166
+ mouse_dragged(area_mouse_event)
11167
+ end
11168
+
11169
+ on_mouse_dropped do |area_mouse_event|
11170
+ mouse_dropped(area_mouse_event)
11171
+ end
11172
+
11173
+ content.call(shape)
11174
+ end
11175
+ end
11176
+
11177
+ def mouse_drag_started(dragged_shape, area_mouse_event)
11178
+ @dragged_shape = dragged_shape
11179
+ @dragged_shape_x = area_mouse_event[:x]
11180
+ @dragged_shape_y = area_mouse_event[:y]
11181
+ end
11182
+
11183
+ def mouse_dragged(area_mouse_event)
11184
+ if @dragged_shape && @dragged_shape_x && @dragged_shape_y
11185
+ x_delta = area_mouse_event[:x] - @dragged_shape_x
11186
+ y_delta = area_mouse_event[:y] - @dragged_shape_y
11187
+ @dragged_shape.move_by(x_delta, y_delta)
11188
+ @dragged_shape_x = area_mouse_event[:x]
11189
+ @dragged_shape_y = area_mouse_event[:y]
11190
+ end
11191
+ end
11192
+
11193
+ def mouse_dropped(area_mouse_event)
11194
+ @dragged_shape = nil
11195
+ @dragged_shape_x = nil
11196
+ @dragged_shape_y = nil
11197
+ end
11198
+ end
11199
+
11200
+ ShapeColoring.launch
11201
+ ```
11202
+
11019
11203
  ## Applications
11020
11204
 
11021
11205
  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.8
1
+ 0.5.11
@@ -0,0 +1,137 @@
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, 220) {
14
+ margined false
15
+
16
+ grid {
17
+ label("Drag & drop shapes to move or\nclick 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) {
47
+ fill :lime
48
+ }
49
+
50
+ @shapes << colorable(:square, 80, 20, 20) {
51
+ fill :blue
52
+ }
53
+
54
+ @shapes << colorable(:circle, 75, 70, 20) {
55
+ fill :green
56
+ }
57
+
58
+ @shapes << colorable(:arc, 120, 70, 40, 0, 145) {
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
+ on_mouse_dragged do |area_mouse_event|
73
+ mouse_dragged(area_mouse_event)
74
+ end
75
+
76
+ on_mouse_dropped do |area_mouse_event|
77
+ mouse_dropped(area_mouse_event)
78
+ end
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ def colorable(shape_symbol, *args, &content)
85
+ send(shape_symbol, *args) do |shape|
86
+ on_mouse_up do |area_mouse_event|
87
+ unless @dragged_shape
88
+ old_stroke = Glimmer::LibUI.interpret_color(shape.stroke).slice(:r, :g, :b)
89
+ @shapes.each {|sh| sh.stroke = nil}
90
+ @selected_shape = nil
91
+ unless old_stroke == COLOR_SELECTION
92
+ shape.stroke = COLOR_SELECTION.merge(thickness: 2)
93
+ @selected_shape = shape
94
+ end
95
+ end
96
+ end
97
+
98
+ on_mouse_drag_started do |area_mouse_event|
99
+ mouse_drag_started(shape, area_mouse_event)
100
+ end
101
+
102
+ on_mouse_dragged do |area_mouse_event|
103
+ mouse_dragged(area_mouse_event)
104
+ end
105
+
106
+ on_mouse_dropped do |area_mouse_event|
107
+ mouse_dropped(area_mouse_event)
108
+ end
109
+
110
+ content.call(shape)
111
+ end
112
+ end
113
+
114
+ def mouse_drag_started(dragged_shape, area_mouse_event)
115
+ @dragged_shape = dragged_shape
116
+ @dragged_shape_x = area_mouse_event[:x]
117
+ @dragged_shape_y = area_mouse_event[:y]
118
+ end
119
+
120
+ def mouse_dragged(area_mouse_event)
121
+ if @dragged_shape && @dragged_shape_x && @dragged_shape_y
122
+ x_delta = area_mouse_event[:x] - @dragged_shape_x
123
+ y_delta = area_mouse_event[:y] - @dragged_shape_y
124
+ @dragged_shape.move_by(x_delta, y_delta)
125
+ @dragged_shape_x = area_mouse_event[:x]
126
+ @dragged_shape_y = area_mouse_event[:y]
127
+ end
128
+ end
129
+
130
+ def mouse_dropped(area_mouse_event)
131
+ @dragged_shape = nil
132
+ @dragged_shape_x = nil
133
+ @dragged_shape_y = nil
134
+ end
135
+ end
136
+
137
+ 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
@@ -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,34 @@ module Glimmer
160
162
  @parent_proxy&.request_auto_redraw
161
163
  end
162
164
 
165
+ def move_by(x_delta, y_delta)
166
+ children.each {|child| child.move_by(x_delta, y_delta)}
167
+ end
168
+
169
+ def perfect_shape
170
+ perfect_shape_dependencies = [draw_fill_mode, children]
171
+ if perfect_shape_dependencies != @perfect_shape_dependencies
172
+ draw_fill_mode, children = @perfect_shape_dependencies = perfect_shape_dependencies
173
+ shapes = children.map(&:perfect_shape)
174
+ new_shapes = []
175
+ shapes.each do |shape|
176
+ if shape.is_a?(PerfectShape::Path)
177
+ new_shapes += shape.basic_shapes
178
+ else
179
+ new_shapes << shape
180
+ end
181
+ end
182
+ shapes = new_shapes
183
+ winding_rule = draw_fill_mode == :winding ? :wind_non_zero : :wind_even_odd
184
+ @perfect_shape = PerfectShape::Path.new(
185
+ shapes: shapes,
186
+ winding_rule: winding_rule,
187
+ line_to_complex_shapes: true
188
+ )
189
+ end
190
+ @perfect_shape
191
+ end
192
+
163
193
  private
164
194
 
165
195
  def build_control
@@ -0,0 +1,65 @@
1
+ require 'forwardable'
2
+
3
+ module Glimmer
4
+ module LibUI
5
+ # GUI View objects that can be represented by PerfectShape objects
6
+ module PerfectShaped
7
+ extend Forwardable
8
+
9
+ def_delegators :perfect_shape,
10
+ :min_x, :min_y, :max_x, :max_y, :center_point, :center_x, :center_y
11
+
12
+ # Returns if shape contains point on the inside when outline is false (default)
13
+ # or if point is on the outline when outline is true
14
+ # distance_tolerance is used when outline is true to enable a fuzz factor in
15
+ # determining if a point lies on the outline (e.g. makes it easier to select
16
+ # a shape by mouse)
17
+ def contain?(*point, outline: false, distance_tolerance: 0)
18
+ perfect_shape&.contain?(*point, outline: outline, distance_tolerance: distance_tolerance)
19
+ end
20
+
21
+ # Returns if shape includes point on the inside when filled
22
+ # or if shape includes point on the outline when stroked
23
+ def include?(*point)
24
+ if fill.empty?
25
+ contain?(*point, outline: true, distance_tolerance: ((stroke[:thickness] || 1) - 1))
26
+ else
27
+ contain?(*point)
28
+ end
29
+ end
30
+
31
+ # Returns bounding box Array consisting of
32
+ # [minx, miny, width, height]
33
+ def bounding_box
34
+ perfect_shape_bounding_box = perfect_shape&.bounding_box
35
+ return if perfect_shape_bounding_box.nil?
36
+ [
37
+ perfect_shape_bounding_box.x,
38
+ perfect_shape_bounding_box.y,
39
+ perfect_shape_bounding_box.width,
40
+ perfect_shape_bounding_box.height,
41
+ ]
42
+ end
43
+
44
+ # moves by x delta and y delta. Classes must implement
45
+ def move_by(x_delta, y_delta)
46
+ # No Op
47
+ end
48
+ alias translate move_by
49
+
50
+ def move(x, y)
51
+ x_delta = x - perfect_shape.min_x
52
+ y_delta = y - perfect_shape.min_y
53
+ move_by(x_delta, y_delta)
54
+ end
55
+
56
+ # Returns PerfectShape object matching this shape to enable
57
+ # executing computational geometry algorithms
58
+ #
59
+ # Including classes must implement
60
+ def perfect_shape
61
+ # No Op
62
+ end
63
+ end
64
+ end
65
+ end
@@ -45,6 +45,11 @@ module Glimmer
45
45
  super
46
46
  end
47
47
 
48
+ def move_by(x_delta, y_delta)
49
+ self.x_center += x_delta
50
+ self.y_center += y_delta
51
+ end
52
+
48
53
  def perfect_shape
49
54
  perfect_shape_dependencies = [x_center, y_center, radius, start_angle, sweep, is_negative]
50
55
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -50,6 +50,17 @@ module Glimmer
50
50
  x && y
51
51
  end
52
52
 
53
+ def move_by(x_delta, y_delta)
54
+ self.x += x_delta
55
+ self.y += y_delta
56
+ self.c1_x += x_delta
57
+ self.c1_y += y_delta
58
+ self.c2_x += x_delta
59
+ self.c2_y += y_delta
60
+ self.end_x += x_delta
61
+ self.end_y += y_delta
62
+ end
63
+
53
64
  def perfect_shape
54
65
  perfect_shape_dependencies = [x, y, c1_x, c1_y, c2_x, c2_y, end_x, end_y]
55
66
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -45,6 +45,11 @@ module Glimmer
45
45
  super
46
46
  end
47
47
 
48
+ def move_by(x_delta, y_delta)
49
+ self.x_center += x_delta
50
+ self.y_center += y_delta
51
+ end
52
+
48
53
  def perfect_shape
49
54
  perfect_shape_dependencies = [x_center, y_center, radius]
50
55
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -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)}
@@ -51,6 +51,12 @@ module Glimmer
51
51
  alias set_closed closed
52
52
  alias closed? closed
53
53
 
54
+ def move_by(x_delta, y_delta)
55
+ self.x += x_delta
56
+ self.y += y_delta
57
+ children.each {|child| child.move_by(x_delta, y_delta)}
58
+ end
59
+
54
60
  def perfect_shape
55
61
  perfect_shape_dependencies = [x, y, closed, parent.draw_fill_mode, children]
56
62
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -58,7 +64,12 @@ module Glimmer
58
64
  path_shapes = [[x, y]]
59
65
  path_shapes += children.map(&:perfect_shape)
60
66
  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)
67
+ @perfect_shape = PerfectShape::Path.new(
68
+ closed: closed,
69
+ winding_rule: winding_rule,
70
+ shapes: path_shapes,
71
+ line_to_complex_shapes: true
72
+ )
62
73
  end
63
74
  @perfect_shape
64
75
  end
@@ -53,6 +53,13 @@ module Glimmer
53
53
  !parent.is_a?(Figure) && end_x && end_y
54
54
  end
55
55
 
56
+ def move_by(x_delta, y_delta)
57
+ self.x += x_delta
58
+ self.y += y_delta
59
+ self.end_x += x_delta
60
+ self.end_y += y_delta
61
+ end
62
+
56
63
  def perfect_shape
57
64
  perfect_shape_dependencies = [x, y, end_x, end_y]
58
65
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -40,6 +40,10 @@ module Glimmer
40
40
  super
41
41
  end
42
42
 
43
+ def move_by(x_delta, y_delta)
44
+ self.point_array = point_array.each_with_index.map {|coordinate, i| i.even? ? coordinate + x_delta : coordinate + y_delta}
45
+ end
46
+
43
47
  def perfect_shape
44
48
  perfect_shape_dependencies = PerfectShape::MultiPoint.normalize_point_array(point_array)
45
49
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -41,6 +41,10 @@ module Glimmer
41
41
  super
42
42
  end
43
43
 
44
+ def move_by(x_delta, y_delta)
45
+ self.point_array = point_array.each_with_index.map {|coordinate, i| i.even? ? coordinate + x_delta : coordinate + y_delta}
46
+ end
47
+
44
48
  def perfect_shape
45
49
  perfect_shape_dependencies = PerfectShape::MultiPoint.normalize_point_array(point_array)
46
50
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -40,6 +40,10 @@ module Glimmer
40
40
  super
41
41
  end
42
42
 
43
+ def move_by(x_delta, y_delta)
44
+ self.point_array = point_array.each_with_index.map {|coordinate, i| i.even? ? coordinate + x_delta : coordinate + y_delta}
45
+ end
46
+
43
47
  def perfect_shape
44
48
  perfect_shape_dependencies = PerfectShape::MultiPoint.normalize_point_array(point_array)
45
49
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -33,6 +33,11 @@ module Glimmer
33
33
  super
34
34
  end
35
35
 
36
+ def move_by(x_delta, y_delta)
37
+ self.x += x_delta
38
+ self.y += y_delta
39
+ end
40
+
36
41
  def perfect_shape
37
42
  perfect_shape_dependencies = [x, y, width, height]
38
43
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -35,6 +35,11 @@ module Glimmer
35
35
 
36
36
  # TODO look into refactoring/unifying code with Rectangle
37
37
 
38
+ def move_by(x_delta, y_delta)
39
+ self.x += x_delta
40
+ self.y += y_delta
41
+ end
42
+
38
43
  def perfect_shape
39
44
  perfect_shape_dependencies = [x, y, length]
40
45
  if perfect_shape_dependencies != @perfect_shape_dependencies
@@ -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)
@@ -209,7 +181,7 @@ module Glimmer
209
181
  super
210
182
  end
211
183
  end
212
-
184
+
213
185
  private
214
186
 
215
187
  def build_control
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.8
4
+ version: 0.5.11
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-26 00:00:00.000000000 Z
11
+ date: 2022-05-21 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.4
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.4
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: super_module
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -355,6 +355,7 @@ files:
355
355
  - examples/midi_player.rb
356
356
  - examples/midi_player2.rb
357
357
  - examples/midi_player3.rb
358
+ - examples/shape_coloring.rb
358
359
  - examples/simple_notepad.rb
359
360
  - examples/snake.rb
360
361
  - examples/snake/model/apple.rb
@@ -471,6 +472,7 @@ files:
471
472
  - lib/glimmer/libui/data_bindable.rb
472
473
  - lib/glimmer/libui/image_path_renderer.rb
473
474
  - lib/glimmer/libui/parent.rb
475
+ - lib/glimmer/libui/perfect_shaped.rb
474
476
  - lib/glimmer/libui/shape.rb
475
477
  - lib/glimmer/libui/shape/arc.rb
476
478
  - lib/glimmer/libui/shape/bezier.rb
@@ -509,7 +511,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
509
511
  - !ruby/object:Gem::Version
510
512
  version: '0'
511
513
  requirements: []
512
- rubygems_version: 3.3.6
514
+ rubygems_version: 3.3.1
513
515
  signing_key:
514
516
  specification_version: 4
515
517
  summary: Glimmer DSL for LibUI