Open seydar opened 1 year ago
I guess I have a couple usage questions:
non_wrapping_multiline_entry
?Here's another example; it should be a green rectangle above a red rectangle, but the red rectangle doesn't appear.
require 'glimmer-dsl-libui'
class Test
include Glimmer
def launch
window("Test", 500, 500) {
margined true
grid {
area {
left 0; xspan 1
top 0; yspan 1
rectangle(0, 0, 500, 200) {
fill 0x00ff00
}
}
area {
left 0; xspan 1
top 1; yspan 1
rectangle(0, 0, 500, 200) {
fill 0x0000ff
}
}
}
}.show
end
end
Test.new.launch
Thank you for submitting this issue.
The last scenario you shared is definitely not supported. It is mentioned in the Glimmer DSL for LibUI API gotchas: https://github.com/AndyObtiva/glimmer-dsl-libui#api-gotchas
It seems that the C libui library does not support nesting multiple area controls under a grid as only the first one shows up in that scenario. To workaround that limitation, use a
vertical_box
with nestedhorizontal_box
s instead to include multiple areas in a GUI.
From doing some testing, it seems non_wrapping_multiline_entry
does not play well with grid
either, but entry
and label
do.
I personally learned to avoid using grid
and just use a combination of horizontal_box
and vertical_box
, sometimes including empty label
controls if I needed to add blank space.
Given that the underlying C libui library is still alpha, it seems like the grid
layout is not ready for prime time yet, especially when including area
or non_wrapping_multiline_entry
in it.
On the other hand, Glimmer DSL for SWT's grid layout is 100% feature complete and solid, including the ability to specify the size of each grid in pixels using layout data. You could try it instead if you're willing to build apps with JRuby.
For example, I built this app using the SWT grid layout, taking advantage of every advanced feature in it:
Math Bowling 2: https://github.com/AndyObtiva/MathBowling
But, going back to Glimmer DSL for LibUI, like I mentioned, I would recommend just using a combination of horizontal_box
and vertical_box
.
If you could provide me with a quick mockup or description of the graphical user interface you are trying to build, maybe I could advise you on how to build it using Glimmer DSL for LibUI.
If you haven't checked the project examples already, I highly recommend checking out the project examples as that's the fastest way to learn it.:
Tetris is a good example of using area
and non-area controls: https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#tetris
Fantastic! Thank you very much for the response.
From doing some testing, it seems non_wrapping_multiline_entry does not play well with grid either, but entry and label do.
I personally learned to avoid using grid and just use a combination of horizontal_box and vertical_box, sometimes including empty label controls if I needed to add blank space.
Given that the underlying C libui library is still alpha, it seems like the grid layout is not ready for prime time yet, especially when including area or non_wrapping_multiline_entry in it.
This is what I was looking to hear — glad I'm not crazy.
Unfortunately, I'm building a GUI for a tool I wrote that leans on the NArray C library in a non-trivial way, so I can't use JRuby/SWT. I've been wrestling with grid
and have gotten it to finally work, although it wasn't easy. Here's what I have so far:
I would like to use a combination of horizontal_box
and vertical_box
, but I don't know how to give them uneven space (like the table on the left and the large graph of vertexes and edges) — my attempts for the above image end up splitting the screen in half. However, you manage to do it in tetris.rb
, so I'm going to play around some more and see what I can make happen.
Thanks again!
Wow! This GUI you built looks amazing! You're some sort of a genius to have figurd this out. Could I include that screenshot in Glimmer DSL for LibUI's Applications? Also, is it an open-source software project by any chance? Would you mind at least sharing how you got the grid working (view code or part of it only)?
By the way, with horizontal_box
and vertical_box
, in order to ensure not all controls have the same size, you set the property stretchy false
for ones that shouldn't stretch to take up all available remaining space. However, I just tested it with area
, and unfortunately, the stretchy
option applied to table
(to prevent it from stretching) does not work correctly when an area
is inside the same horizontal_box
along with it. I reported the issue (and other issues) to the upstream libui-ng C library project: https://github.com/libui-ng/libui-ng/issues/216
I'm so glad you like it, thank you so much! Please feel free to include the screenshot wherever you want!
I would like it to be open source, but I'm trying to use this software to maybe start a company, so I can't quite release it yet until I figure out how to somehow find work with the underlying software.
That said, I'm working on rewriting the GUI to use MVP, so I can definitely make the GUI open source. I'll have it up shortly and let you know.
It doesn't have to be open-source at all. I only asked just in case so I'd learn more about the project. But, I respect closed-source software too, especially when it's for a business. I work for a company with closed source software, so I totally understand. You don't have to open-source it.
Thank you for allowing me to share the screenshot. I added it under Glimmer DSL for LibUI Applications: https://github.com/AndyObtiva/glimmer-dsl-libui/tree/master#electric-avenue
Here's the GUI code for it (I just tried to rewrite it to be more like MVP with observers, but it's tough — I'm not used to this style, or GUI programming in general).
https://github.com/seydar/electric_gui
I'm open to any feedback you have on how I should structure things.
OK, thank you for sharing. I will take a look when I get a chance.
I took a look.
Your app.rb
generally looks good. I like how you abstracted components out into methods.
In Glimmer DSL for LibUI terminology, this technique is called Method-Based Custom Keywords. Or, more casually, method-based custom controls (components).
Also, I liked your usage of data-binding and how it pulled data cleanly from pure presenters (overall.rb
and congestion.rb
). It was very well done.
I noticed that you declared histogram.rb
(and plotter.rb
) as a Presenter. However, it is used as a View given that it is rendering GUI. Usually, Presenters present information that is summarized from Models as pure data, and then that pure data is rendered as GUI in Views outside of Presenters (a layer above). And, Presenters generally don't mix in Glimmer
. They're a layer below Glimmer
(which is only mixed into Views in general).
You could have avoided that by extracting this bit of code from app.rb
into histogram.rb
, and putting histogram.rb
under a views
directory.
@hist = area {
left x; xspan xs
top y; yspan ys
vexpand true
on_draw do |area|
rectangle(0, 0, area[:area_width], area[:area_height]) {
fill 0xFFFFFF
}
@histogram.plot area
end
}
The same could have been done for plotter.rb
:
@plot = area {
left x; xspan xs
top y; yspan ys
on_draw {|area|
@plotter.scale_area area, PLOT
self.desc = grid_description
# Background
rectangle(0, 0, area[:area_width], area[:area_height]) {
fill 0xffffff
}
# Graph
@plotter.plot_flows
# Info
@plotter.plot_info_box
}
on_mouse_up do |area_event|
@plotter.select_info_box(area_event[:x], area_event[:y])
@plot.queue_redraw_all
end
}
To do that, you could use the other Glimmer DSL for LibUI custom control technique, which is called Class-Based Custom Keywords, or class-based custom controls. Glimmer will automatically convert such classes into underscored keywords. So, if you declare a Histogram
custom control, you can later use it with histogram
in a View that mixes Glimmer
. A Plotter
class becomes plotter
in Glimmer
View code.
This code is a small example of how to build a class-based custom control (it generates the address_view
keyword):
class AddressView
include Glimmer::LibUI::CustomControl
options :address
body {
vertical_box {
address.each_pair do |attribute, value|
label_pair(model: address, attribute: attribute, value: value)
end
}
}
end
This can later be used from another View like this:
window {
horizontal_box {
address_view(address: shipping_address)
address_view(address: billing_address)
}
}
To learn more how to build class-based custom controls, I highly recommend checking out the examples/class_based_custom_controls.rb
example:
https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#class-based-custom-controls
Another bit of feedback is app.rb
could have taken advantage of the new Glimmer DSL for LibUI module for building applications Glimmer::LibUI::Application
(aka Glimmer::LibUI::CustomWindow
):
https://github.com/AndyObtiva/glimmer-dsl-libui#usage
It expects declaring the GUI code cleanly inside body
, and it takes care of the rest whe you call ClassName.launch
(it also supports before_body
and after_body
hooks in case there is a need to execute code before or after initialization of the body, so any code in initialize
goes into before_body
if you refactor).
require 'glimmer-dsl-libui'
class SomeGlimmerApp
include Glimmer::LibUI::Application
body {
window('hello world', 300, 200) {
button('Button') {
on_clicked do
puts 'Button Clicked'
end
}
}
}
end
SomeGlimmerApp.launch
In summary:
app.rb
is great! That technique is called method-based custom controls.overall.rb
and congestion.rb
is great.app.rb
could optionally use include Glimmer::LibUI::Application
instead of include Glimmer
to automate some of the boilerplate work. Any code that was in initialize
would move to before_body
if you make this refactoring.plotter.rb
) should become a class-based custom control and live in a views
directory. Glimmer
. This is OPTIONAL and is not always necessary. Sometimes, the logic is simple enough to just live inside the View (custom control) classes.models
directory to store Model classes that you rely on in the Presenters as a lower layer that provides the base data before it is summarized in a form that could be rendered in a View. This is not needed if your Model layer is actually living outside the application in some library (like in electric_avenue.rb
)I hope that I provided enough feedback. If you have any further questions, feel free to ask.
Cheers.
I am 100% sure that this is a PEBKAC case, but I'm not sure where else to turn:
Shows up as the attached image.
What's happening: the rectangle is all the way to the left What should happen: the rectangle should begin within its spot in the grid.
Obviously, I recognize that this is just my unfamiliarity with library, but I'm hoping for some guidance on where to turn to.