glimmer-dsl-opal 0.7.4 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +95 -45
- data/VERSION +1 -1
- data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +50 -23
- data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +22 -5
- data/lib/glimmer/dsl/opal/custom_widget_expression.rb +2 -1
- data/lib/glimmer/swt/grid_layout_proxy.rb +13 -4
- data/lib/glimmer/swt/layout_data_proxy.rb +2 -5
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c18e541c8e9442edb881c4a2209b920ec5891c770901cd4474d93875d6a9d785
|
4
|
+
data.tar.gz: aadee7ddedd9a598e32784105d408b619c8503ef7aeb58d18253d1a505115e8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d0efad3abf372c53a9f214fe6e9ad2a9b4a4f18413acded585411742f1eb0fdd3dff3939bb2e64e905f55c59c5c0c686e7715fd2f01ed70c7f6a4005e67ac3a
|
7
|
+
data.tar.gz: 247c8c74ca777009bee85b89eb8ba137d5a389a55cb6f845f70d49b6b331184e625196c9dd1b07797730bc1c853ba87f7eae437356ef2e56fa26240854d5c706
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.7.5
|
4
|
+
|
5
|
+
- Update login sample from Glimmer DSL for SWT's latest changes
|
6
|
+
- Update contact_manager sample from Glimmer DSL for SWT's latest changes
|
7
|
+
- Fixed issue regarding unavailable localStorage data when accessed by custom_widget_expression in hello_checkbox_group, hello_radio_group, and hello_custom_widget
|
8
|
+
|
3
9
|
## 0.7.4
|
4
10
|
|
5
11
|
- Hello, Button! Sample
|
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 Opal 0.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 Opal 0.7.5 (Pure Ruby Web GUI)
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-opal.svg)](http://badge.fury.io/rb/glimmer-dsl-opal)
|
3
3
|
[![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)
|
4
4
|
|
@@ -52,15 +52,15 @@ Tic Tac Toe on the web (using the [glimmer-dsl-opal](https://rubygems.org/gems/g
|
|
52
52
|
![Glimmer DSL for Opal Tic Tac Toe In Progress](images/glimmer-dsl-opal-tic-tac-toe-in-progress.png)
|
53
53
|
![Glimmer DSL for Opal Tic Tac Toe Game Over](images/glimmer-dsl-opal-tic-tac-toe-game-over.png)
|
54
54
|
|
55
|
-
Tic Tac Toe on the desktop with the same exact code (using the [
|
55
|
+
Tic Tac Toe on the desktop with the same exact code (using the [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
56
56
|
|
57
57
|
![Glimmer DSL for SWT Tic Tac Toe](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe.png)
|
58
58
|
![Glimmer DSL for SWT Tic Tac Toe In Progress](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe-in-progress.png)
|
59
59
|
![Glimmer DSL for SWT Tic Tac Toe Game Over](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe-game-over.png)
|
60
60
|
|
61
|
-
NOTE: **Alpha Version** 0.7.
|
61
|
+
NOTE: **Alpha Version** 0.7.5 only supports bare-minimum capabilities for the following [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally made for [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)):
|
62
62
|
|
63
|
-
Hello:
|
63
|
+
[Hello samples](#hello-samples):
|
64
64
|
|
65
65
|
- [Hello, World!](#hello-world)
|
66
66
|
- [Hello, Combo!](#hello-combo)
|
@@ -80,7 +80,7 @@ Hello:
|
|
80
80
|
- [Hello, Table!](#hello-table)
|
81
81
|
- [Hello, Button!](#hello-button)
|
82
82
|
|
83
|
-
Elaborate:
|
83
|
+
[Elaborate samples](#elaborate-samples):
|
84
84
|
|
85
85
|
- [Login](#login)
|
86
86
|
- [Tic Tac Toe](#tic-tac-toe)
|
@@ -136,6 +136,13 @@ Event loop:
|
|
136
136
|
- `display`
|
137
137
|
- `async_exec`
|
138
138
|
|
139
|
+
## Principles
|
140
|
+
|
141
|
+
- **Live purely in Rubyland via the Glimmer GUI DSL**, completely oblivious to web browser technologies.
|
142
|
+
- **Forget Routers!** Glimmer DSL for Opal supports auto-routing of custom shells (windows), which are opened as separate tabs in a web browser with automatically generated routes and bookmarkable URLs.
|
143
|
+
- **HTML is strictly made for creating documents not interactive applications**. As such, software engineers can avoid it and focus on creating web applications more productively with Glimmer DSL for Opal in pure Ruby (just like they do in desktop development) while content creators and web designers can be the ones responsible for creating HTML documents for web content purposes only as HTML was originally intended. Web designers may also style Glimmer DSL for Opal applications since they auto-generate symantic markup. That way, Glimmer web GUI is used and embedded in web pages that provide users with applications while the rest of the web pages are maintained by non-engineers. This achieves a correct separation of responsibilities and better productivity and maintainability.
|
144
|
+
- **Web servers are used just like servers in traditional client/server architecture**, meaning they simply provide RMI services to enable centralizing some of the application logic and data in the cloud to make available everywhere and enable data-sharing with others.
|
145
|
+
|
139
146
|
## Background
|
140
147
|
|
141
148
|
The original idea behind Glimmer DSL for Opal was that you start by having a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app that communicates with a Rails API for any web/cloud concerns. The pure Ruby [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is very simple, so it is more productive to build GUI in it since it does not go through a server/client request/response cycle and can be iterated on locally with a much shorter feedback cycle. Once the GUI and the rest of the app is built. You simply embed it in a Rails app as a one line require statement after adding the Glimmer DSL for Opal gem, and BOOM, it just works on the web inside a web browser with the same server/client communication you had in the desktop app (I am working on adding minimal support for net/http in Opal so that desktop apps that use it continue to work in a web browser. Until then, just use [Opal-jQuery](https://github.com/opal/opal-jquery) http support). That way, you get two apps for one: desktop and web.
|
@@ -146,12 +153,6 @@ Last but not least, you would likely want some special branding on the web, so y
|
|
146
153
|
|
147
154
|
Alternatively, web developers may directly use [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) to build the GUI of web apps since it is as simple as desktop development, thus requiring a lot less code that is in pure Ruby only (as demonstrated in examples below) and avoiding opaque web concepts like 'render' and 'reactive' due to treating GUI as persistent just like desktop apps do. No HTML/JS/CSS skills are even required. Still, web designers may be involved with CSS only if needed, thanks to the clean semantic markup [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) automatically produces.
|
148
155
|
|
149
|
-
## Principles
|
150
|
-
|
151
|
-
- Live purely in Rubyland via the Glimmer GUI DSL, completely oblivious to web browser technologies.
|
152
|
-
- Forget Routers! Glimmer DSL for Opal supports auto-routing of custom shells (windows), which are opened as separate tabs in a web browser with automatically generated routes and bookmarkable URLs.
|
153
|
-
- HTML is strictly made for creating documents not interactive applications. As such, software engineers can avoid and focus on creating web applications with Glimmer DSL for Opal in pure Ruby while content creators and web designers are the ones responsible for creating HTML documents for content purposes only as HTML was originally intended. As such, Glimmer web GUI built by software engineers gets embedded in the body of a web page with content around it maintained by content creators and web designers. This achieves a correct separation of responsibilities and better maintainability.
|
154
|
-
|
155
156
|
## Pre-requisites
|
156
157
|
|
157
158
|
- Rails 5: [https://github.com/rails/rails/tree/5-2-stable](https://github.com/rails/rails/tree/5-2-stable)
|
@@ -186,7 +187,7 @@ Add the following to `Gemfile`:
|
|
186
187
|
gem 'opal-rails', '~> 1.1.2'
|
187
188
|
gem 'opal-async', '~> 1.2.0'
|
188
189
|
gem 'opal-jquery', '~> 0.4.4'
|
189
|
-
gem 'glimmer-dsl-opal', '~> 0.7.
|
190
|
+
gem 'glimmer-dsl-opal', '~> 0.7.5'
|
190
191
|
gem 'glimmer-dsl-xml', '~> 1.1.0', require: false
|
191
192
|
gem 'glimmer-dsl-css', '~> 1.1.0', require: false
|
192
193
|
|
@@ -255,11 +256,17 @@ end
|
|
255
256
|
|
256
257
|
Follow the instructions below to try out [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) samples webified via [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal)
|
257
258
|
|
258
|
-
|
259
|
+
The [Hello samples](#hello-samples) demonstrate tiny building blocks for building full fledged applications. The [Elaborate samples](#elaborate-samples) demonstrate more advanced sample applications that assemble multiple building blocks.
|
260
|
+
|
261
|
+
This external sample app contains all the samples mentioned below configured inside a Rails [Opal](https://opalrb.com/) app with all the pre-requisites ready to go for convenience:
|
262
|
+
|
263
|
+
[https://github.com/AndyObtiva/sample-glimmer-dsl-opal-rails-app](https://github.com/AndyObtiva/sample-glimmer-dsl-opal-rails-app)
|
259
264
|
|
260
|
-
|
265
|
+
You may visit a Heroku hosted version at:
|
261
266
|
|
262
|
-
|
267
|
+
https://sample-glimmer-dsl-opal-app.herokuapp.com/
|
268
|
+
|
269
|
+
Note: Some of the screenshots might be out of date with updates done to samples in both [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) and [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal).
|
263
270
|
|
264
271
|
### Hello Samples
|
265
272
|
|
@@ -1970,7 +1977,6 @@ Or add the Glimmer code directly if you prefer to play around with it:
|
|
1970
1977
|
```ruby
|
1971
1978
|
require "observer"
|
1972
1979
|
|
1973
|
-
#Presents login screen data
|
1974
1980
|
class LoginPresenter
|
1975
1981
|
|
1976
1982
|
attr_accessor :user_name
|
@@ -1986,10 +1992,13 @@ class LoginPresenter
|
|
1986
1992
|
def status=(status)
|
1987
1993
|
@status = status
|
1988
1994
|
|
1989
|
-
#TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
|
1990
1995
|
notify_observers("logged_in")
|
1991
1996
|
notify_observers("logged_out")
|
1992
1997
|
end
|
1998
|
+
|
1999
|
+
def valid?
|
2000
|
+
!@user_name.to_s.strip.empty? && !@password.to_s.strip.empty?
|
2001
|
+
end
|
1993
2002
|
|
1994
2003
|
def logged_in
|
1995
2004
|
self.status == "Logged In"
|
@@ -2000,6 +2009,7 @@ class LoginPresenter
|
|
2000
2009
|
end
|
2001
2010
|
|
2002
2011
|
def login
|
2012
|
+
return unless valid?
|
2003
2013
|
self.status = "Logged In"
|
2004
2014
|
end
|
2005
2015
|
|
@@ -2011,7 +2021,6 @@ class LoginPresenter
|
|
2011
2021
|
|
2012
2022
|
end
|
2013
2023
|
|
2014
|
-
#Login screen
|
2015
2024
|
class Login
|
2016
2025
|
include Glimmer
|
2017
2026
|
|
@@ -2023,15 +2032,21 @@ class Login
|
|
2023
2032
|
grid_layout 2, false #two columns with differing widths
|
2024
2033
|
|
2025
2034
|
label { text "Username:" } # goes in column 1
|
2026
|
-
text {
|
2035
|
+
@user_name_text = text { # goes in column 2
|
2027
2036
|
text bind(presenter, :user_name)
|
2028
2037
|
enabled bind(presenter, :logged_out)
|
2038
|
+
on_key_pressed { |event|
|
2039
|
+
@password_text.set_focus if event.keyCode == swt(:cr)
|
2040
|
+
}
|
2029
2041
|
}
|
2030
2042
|
|
2031
2043
|
label { text "Password:" }
|
2032
|
-
text(:password, :border) {
|
2044
|
+
@password_text = text(:password, :border) {
|
2033
2045
|
text bind(presenter, :password)
|
2034
2046
|
enabled bind(presenter, :logged_out)
|
2047
|
+
on_key_pressed { |event|
|
2048
|
+
presenter.login if event.keyCode == swt(:cr)
|
2049
|
+
}
|
2035
2050
|
}
|
2036
2051
|
|
2037
2052
|
label { text "Status:" }
|
@@ -2041,12 +2056,21 @@ class Login
|
|
2041
2056
|
text "Login"
|
2042
2057
|
enabled bind(presenter, :logged_out)
|
2043
2058
|
on_widget_selected { presenter.login }
|
2059
|
+
on_key_pressed { |event|
|
2060
|
+
presenter.login if event.keyCode == swt(:cr)
|
2061
|
+
}
|
2044
2062
|
}
|
2045
2063
|
|
2046
2064
|
button {
|
2047
2065
|
text "Logout"
|
2048
2066
|
enabled bind(presenter, :logged_in)
|
2049
2067
|
on_widget_selected { presenter.logout }
|
2068
|
+
on_key_pressed { |event|
|
2069
|
+
if event.keyCode == swt(:cr)
|
2070
|
+
presenter.logout
|
2071
|
+
@user_name_text.set_focus
|
2072
|
+
end
|
2073
|
+
}
|
2050
2074
|
}
|
2051
2075
|
}
|
2052
2076
|
}
|
@@ -2529,41 +2553,76 @@ class ContactManager
|
|
2529
2553
|
shell {
|
2530
2554
|
text "Contact Manager"
|
2531
2555
|
composite {
|
2532
|
-
|
2533
|
-
grid_layout
|
2534
|
-
|
2556
|
+
group {
|
2557
|
+
grid_layout(2, false) {
|
2558
|
+
margin_width 0
|
2559
|
+
margin_height 0
|
2560
|
+
}
|
2561
|
+
layout_data :fill, :center, true, false
|
2562
|
+
text 'Lookup Contacts'
|
2563
|
+
font height: 24
|
2564
|
+
|
2565
|
+
label {
|
2566
|
+
layout_data :right, :center, false, false
|
2567
|
+
text "First &Name: "
|
2568
|
+
font height: 16
|
2569
|
+
}
|
2535
2570
|
text {
|
2571
|
+
layout_data :fill, :center, true, false
|
2536
2572
|
text bind(@contact_manager_presenter, :first_name)
|
2537
2573
|
on_key_pressed {|key_event|
|
2538
|
-
@contact_manager_presenter.find if key_event.keyCode ==
|
2574
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
2539
2575
|
}
|
2540
2576
|
}
|
2541
|
-
|
2577
|
+
|
2578
|
+
label {
|
2579
|
+
layout_data :right, :center, false, false
|
2580
|
+
text "&Last Name: "
|
2581
|
+
font height: 16
|
2582
|
+
}
|
2542
2583
|
text {
|
2584
|
+
layout_data :fill, :center, true, false
|
2543
2585
|
text bind(@contact_manager_presenter, :last_name)
|
2544
2586
|
on_key_pressed {|key_event|
|
2545
|
-
@contact_manager_presenter.find if key_event.keyCode ==
|
2587
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
2546
2588
|
}
|
2547
2589
|
}
|
2548
|
-
|
2590
|
+
|
2591
|
+
label {
|
2592
|
+
layout_data :right, :center, false, false
|
2593
|
+
text "&Email: "
|
2594
|
+
font height: 16
|
2595
|
+
}
|
2549
2596
|
text {
|
2597
|
+
layout_data :fill, :center, true, false
|
2550
2598
|
text bind(@contact_manager_presenter, :email)
|
2551
2599
|
on_key_pressed {|key_event|
|
2552
|
-
@contact_manager_presenter.find if key_event.keyCode ==
|
2600
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
2553
2601
|
}
|
2554
2602
|
}
|
2603
|
+
|
2555
2604
|
composite {
|
2556
|
-
|
2605
|
+
row_layout {
|
2606
|
+
margin_width 0
|
2607
|
+
margin_height 0
|
2608
|
+
}
|
2609
|
+
layout_data(:right, :center, false, false) {
|
2610
|
+
horizontal_span 2
|
2611
|
+
}
|
2612
|
+
|
2557
2613
|
button {
|
2558
2614
|
text "&Find"
|
2559
|
-
on_widget_selected {
|
2560
|
-
|
2615
|
+
on_widget_selected { @contact_manager_presenter.find }
|
2616
|
+
on_key_pressed {|key_event|
|
2617
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
2561
2618
|
}
|
2562
2619
|
}
|
2620
|
+
|
2563
2621
|
button {
|
2564
2622
|
text "&List All"
|
2565
|
-
on_widget_selected {
|
2566
|
-
|
2623
|
+
on_widget_selected { @contact_manager_presenter.list }
|
2624
|
+
on_key_pressed {|key_event|
|
2625
|
+
@contact_manager_presenter.list if key_event.keyCode == swt(:cr)
|
2567
2626
|
}
|
2568
2627
|
}
|
2569
2628
|
}
|
@@ -2580,26 +2639,18 @@ class ContactManager
|
|
2580
2639
|
table_column {
|
2581
2640
|
text "First Name"
|
2582
2641
|
width 80
|
2583
|
-
on_widget_selected {
|
2584
|
-
@contact_manager_presenter.toggle_sort(:first_name)
|
2585
|
-
}
|
2586
2642
|
}
|
2587
2643
|
table_column {
|
2588
2644
|
text "Last Name"
|
2589
2645
|
width 80
|
2590
|
-
on_widget_selected {
|
2591
|
-
@contact_manager_presenter.toggle_sort(:last_name)
|
2592
|
-
}
|
2593
2646
|
}
|
2594
2647
|
table_column {
|
2595
2648
|
text "Email"
|
2596
2649
|
width 200
|
2597
|
-
on_widget_selected {
|
2598
|
-
@contact_manager_presenter.toggle_sort(:email)
|
2599
|
-
}
|
2600
2650
|
}
|
2601
|
-
items bind(@contact_manager_presenter, :results),
|
2602
|
-
|
2651
|
+
items bind(@contact_manager_presenter, :results),
|
2652
|
+
column_properties(:first_name, :last_name, :email)
|
2653
|
+
on_mouse_up { |event|
|
2603
2654
|
table_proxy.edit_table_item(event.table_item, event.column_index)
|
2604
2655
|
}
|
2605
2656
|
}
|
@@ -2609,7 +2660,6 @@ class ContactManager
|
|
2609
2660
|
end
|
2610
2661
|
|
2611
2662
|
ContactManager.new.launch
|
2612
|
-
|
2613
2663
|
```
|
2614
2664
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2615
2665
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.5
|
@@ -12,41 +12,76 @@ class ContactManager
|
|
12
12
|
shell {
|
13
13
|
text "Contact Manager"
|
14
14
|
composite {
|
15
|
-
|
16
|
-
grid_layout
|
17
|
-
|
15
|
+
group {
|
16
|
+
grid_layout(2, false) {
|
17
|
+
margin_width 0
|
18
|
+
margin_height 0
|
19
|
+
}
|
20
|
+
layout_data :fill, :center, true, false
|
21
|
+
text 'Lookup Contacts'
|
22
|
+
font height: 24
|
23
|
+
|
24
|
+
label {
|
25
|
+
layout_data :right, :center, false, false
|
26
|
+
text "First &Name: "
|
27
|
+
font height: 16
|
28
|
+
}
|
18
29
|
text {
|
30
|
+
layout_data :fill, :center, true, false
|
19
31
|
text bind(@contact_manager_presenter, :first_name)
|
20
32
|
on_key_pressed {|key_event|
|
21
|
-
@contact_manager_presenter.find if key_event.keyCode ==
|
33
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
22
34
|
}
|
23
35
|
}
|
24
|
-
|
36
|
+
|
37
|
+
label {
|
38
|
+
layout_data :right, :center, false, false
|
39
|
+
text "&Last Name: "
|
40
|
+
font height: 16
|
41
|
+
}
|
25
42
|
text {
|
43
|
+
layout_data :fill, :center, true, false
|
26
44
|
text bind(@contact_manager_presenter, :last_name)
|
27
45
|
on_key_pressed {|key_event|
|
28
|
-
@contact_manager_presenter.find if key_event.keyCode ==
|
46
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
29
47
|
}
|
30
48
|
}
|
31
|
-
|
49
|
+
|
50
|
+
label {
|
51
|
+
layout_data :right, :center, false, false
|
52
|
+
text "&Email: "
|
53
|
+
font height: 16
|
54
|
+
}
|
32
55
|
text {
|
56
|
+
layout_data :fill, :center, true, false
|
33
57
|
text bind(@contact_manager_presenter, :email)
|
34
58
|
on_key_pressed {|key_event|
|
35
|
-
@contact_manager_presenter.find if key_event.keyCode ==
|
59
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
36
60
|
}
|
37
61
|
}
|
62
|
+
|
38
63
|
composite {
|
39
|
-
|
64
|
+
row_layout {
|
65
|
+
margin_width 0
|
66
|
+
margin_height 0
|
67
|
+
}
|
68
|
+
layout_data(:right, :center, false, false) {
|
69
|
+
horizontal_span 2
|
70
|
+
}
|
71
|
+
|
40
72
|
button {
|
41
73
|
text "&Find"
|
42
|
-
on_widget_selected {
|
43
|
-
|
74
|
+
on_widget_selected { @contact_manager_presenter.find }
|
75
|
+
on_key_pressed {|key_event|
|
76
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
44
77
|
}
|
45
78
|
}
|
79
|
+
|
46
80
|
button {
|
47
81
|
text "&List All"
|
48
|
-
on_widget_selected {
|
49
|
-
|
82
|
+
on_widget_selected { @contact_manager_presenter.list }
|
83
|
+
on_key_pressed {|key_event|
|
84
|
+
@contact_manager_presenter.list if key_event.keyCode == swt(:cr)
|
50
85
|
}
|
51
86
|
}
|
52
87
|
}
|
@@ -63,25 +98,17 @@ class ContactManager
|
|
63
98
|
table_column {
|
64
99
|
text "First Name"
|
65
100
|
width 80
|
66
|
-
on_widget_selected {
|
67
|
-
@contact_manager_presenter.toggle_sort(:first_name)
|
68
|
-
}
|
69
101
|
}
|
70
102
|
table_column {
|
71
103
|
text "Last Name"
|
72
104
|
width 80
|
73
|
-
on_widget_selected {
|
74
|
-
@contact_manager_presenter.toggle_sort(:last_name)
|
75
|
-
}
|
76
105
|
}
|
77
106
|
table_column {
|
78
107
|
text "Email"
|
79
108
|
width 200
|
80
|
-
on_widget_selected {
|
81
|
-
@contact_manager_presenter.toggle_sort(:email)
|
82
|
-
}
|
83
109
|
}
|
84
|
-
items bind(@contact_manager_presenter, :results),
|
110
|
+
items bind(@contact_manager_presenter, :results),
|
111
|
+
column_properties(:first_name, :last_name, :email)
|
85
112
|
on_mouse_up { |event|
|
86
113
|
table_proxy.edit_table_item(event.table_item, event.column_index)
|
87
114
|
}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require "observer"
|
2
2
|
|
3
|
-
#Presents login screen data
|
4
3
|
class LoginPresenter
|
5
4
|
|
6
5
|
attr_accessor :user_name
|
@@ -16,10 +15,13 @@ class LoginPresenter
|
|
16
15
|
def status=(status)
|
17
16
|
@status = status
|
18
17
|
|
19
|
-
#TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
|
20
18
|
notify_observers("logged_in")
|
21
19
|
notify_observers("logged_out")
|
22
20
|
end
|
21
|
+
|
22
|
+
def valid?
|
23
|
+
!@user_name.to_s.strip.empty? && !@password.to_s.strip.empty?
|
24
|
+
end
|
23
25
|
|
24
26
|
def logged_in
|
25
27
|
self.status == "Logged In"
|
@@ -30,6 +32,7 @@ class LoginPresenter
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def login
|
35
|
+
return unless valid?
|
33
36
|
self.status = "Logged In"
|
34
37
|
end
|
35
38
|
|
@@ -41,7 +44,6 @@ class LoginPresenter
|
|
41
44
|
|
42
45
|
end
|
43
46
|
|
44
|
-
#Login screen
|
45
47
|
class Login
|
46
48
|
include Glimmer
|
47
49
|
|
@@ -53,15 +55,21 @@ class Login
|
|
53
55
|
grid_layout 2, false #two columns with differing widths
|
54
56
|
|
55
57
|
label { text "Username:" } # goes in column 1
|
56
|
-
text {
|
58
|
+
@user_name_text = text { # goes in column 2
|
57
59
|
text bind(presenter, :user_name)
|
58
60
|
enabled bind(presenter, :logged_out)
|
61
|
+
on_key_pressed { |event|
|
62
|
+
@password_text.set_focus if event.keyCode == swt(:cr)
|
63
|
+
}
|
59
64
|
}
|
60
65
|
|
61
66
|
label { text "Password:" }
|
62
|
-
text(:password, :border) {
|
67
|
+
@password_text = text(:password, :border) {
|
63
68
|
text bind(presenter, :password)
|
64
69
|
enabled bind(presenter, :logged_out)
|
70
|
+
on_key_pressed { |event|
|
71
|
+
presenter.login if event.keyCode == swt(:cr)
|
72
|
+
}
|
65
73
|
}
|
66
74
|
|
67
75
|
label { text "Status:" }
|
@@ -71,12 +79,21 @@ class Login
|
|
71
79
|
text "Login"
|
72
80
|
enabled bind(presenter, :logged_out)
|
73
81
|
on_widget_selected { presenter.login }
|
82
|
+
on_key_pressed { |event|
|
83
|
+
presenter.login if event.keyCode == swt(:cr)
|
84
|
+
}
|
74
85
|
}
|
75
86
|
|
76
87
|
button {
|
77
88
|
text "Logout"
|
78
89
|
enabled bind(presenter, :logged_in)
|
79
90
|
on_widget_selected { presenter.logout }
|
91
|
+
on_key_pressed { |event|
|
92
|
+
if event.keyCode == swt(:cr)
|
93
|
+
presenter.logout
|
94
|
+
@user_name_text.set_focus
|
95
|
+
end
|
96
|
+
}
|
80
97
|
}
|
81
98
|
}
|
82
99
|
}
|
@@ -43,7 +43,8 @@ module Glimmer
|
|
43
43
|
|
44
44
|
def interpret(parent, keyword, *args, &block)
|
45
45
|
begin
|
46
|
-
|
46
|
+
require_path = `localStorage[#{keyword}]`
|
47
|
+
require(require_path) if require_path
|
47
48
|
rescue => e
|
48
49
|
Glimmer::Config.logger.debug e.message
|
49
50
|
end
|
@@ -17,6 +17,8 @@ module Glimmer
|
|
17
17
|
super(parent, args)
|
18
18
|
self.horizontal_spacing = 10
|
19
19
|
self.vertical_spacing = 10
|
20
|
+
self.margin_width = 15
|
21
|
+
self.margin_height = 15
|
20
22
|
self.num_columns = @args.first || 1
|
21
23
|
reapply
|
22
24
|
end
|
@@ -49,14 +51,18 @@ module Glimmer
|
|
49
51
|
def margin_width=(pixels)
|
50
52
|
@margin_width = pixels
|
51
53
|
# Using padding for width since margin-right isn't getting respected with width 100%
|
52
|
-
|
53
|
-
@parent.
|
54
|
+
effective_margin_width = @margin_width
|
55
|
+
effective_margin_width += 6 if @parent.is_a?(GroupProxy)
|
56
|
+
@parent.dom_element.css('padding-left', effective_margin_width)
|
57
|
+
@parent.dom_element.css('padding-right', effective_margin_width)
|
54
58
|
end
|
55
59
|
|
56
60
|
def margin_height=(pixels)
|
57
61
|
@margin_height = pixels
|
58
|
-
|
59
|
-
@parent.
|
62
|
+
effective_margin_height = @margin_height
|
63
|
+
effective_margin_height += 9 if @parent.is_a?(GroupProxy)
|
64
|
+
@parent.dom_element.css('padding-top', effective_margin_height)
|
65
|
+
@parent.dom_element.css('padding-bottom', effective_margin_height)
|
60
66
|
end
|
61
67
|
|
62
68
|
def reapply
|
@@ -70,6 +76,9 @@ module Glimmer
|
|
70
76
|
layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
|
71
77
|
@parent.dom_element.css(key, value) unless key.nil?
|
72
78
|
end
|
79
|
+
if @parent.is_a?(GroupProxy)
|
80
|
+
@parent.dom_element.find('legend').css('grid-column-start', "span #{@num_columns.to_i}")
|
81
|
+
end
|
73
82
|
else
|
74
83
|
layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
|
75
84
|
@parent.dom_element.css(key, 'initial') unless key.nil?
|
@@ -45,9 +45,7 @@ module Glimmer
|
|
45
45
|
def horizontal_alignment=(horizontal_alignment)
|
46
46
|
@horizontal_alignment = horizontal_alignment
|
47
47
|
return if @horizontal_alignment.nil?
|
48
|
-
if @horizontal_alignment
|
49
|
-
@parent.dom_element.css('width', '100%') if width_hint.nil?
|
50
|
-
else
|
48
|
+
if @horizontal_alignment != 'fill'
|
51
49
|
@parent.dom_element.css('text-align', @horizontal_alignment.to_s)
|
52
50
|
@parent.dom_element.css('place-self', @horizontal_alignment.to_s)
|
53
51
|
@parent.dom_element.css('margin-left', 'auto') if ['right', 'center'].include?(@horizontal_alignment.to_s)
|
@@ -89,7 +87,6 @@ module Glimmer
|
|
89
87
|
|
90
88
|
def grab_excess_horizontal_space=(grab_excess_horizontal_space)
|
91
89
|
@grab_excess_horizontal_space = grab_excess_horizontal_space
|
92
|
-
@parent.dom_element.css('width', "100%") if @grab_excess_horizontal_space && @horizontal_alignment == 'fill' && width_hint.nil?
|
93
90
|
@parent.dom_element.css('justify-self', @horizontal_alignment) if @grab_excess_horizontal_space && @horizontal_alignment != 'fill' && width_hint.nil?
|
94
91
|
@parent.parent.dom_element.css('justify-content', "normal") if @grab_excess_horizontal_space
|
95
92
|
# reapply
|
@@ -98,11 +95,11 @@ module Glimmer
|
|
98
95
|
def grab_excess_vertical_space=(grab_excess_vertical_space)
|
99
96
|
@grab_excess_vertical_space = grab_excess_vertical_space
|
100
97
|
@parent.dom_element.css('height', "100%") if @grab_excess_vertical_space && @vertical_alignment == 'fill' && height_hint.nil?
|
101
|
-
# TODO
|
102
98
|
# reapply
|
103
99
|
end
|
104
100
|
|
105
101
|
def reapply
|
102
|
+
# TODO remove reapply method
|
106
103
|
# @parent.css = <<~CSS
|
107
104
|
# CSS
|
108
105
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-opal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -210,7 +210,8 @@ dependencies:
|
|
210
210
|
- - "~>"
|
211
211
|
- !ruby/object:Gem::Version
|
212
212
|
version: 0.4.4
|
213
|
-
description: Glimmer DSL for Opal (Web GUI
|
213
|
+
description: Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop
|
214
|
+
Apps Running via Opal on Rails)
|
214
215
|
email: andy.am@gmail.com
|
215
216
|
executables: []
|
216
217
|
extensions: []
|