Comments (16)
As currently written, there is no way in Shoes to reliably manage other Apps/Wiindows. It is confounded by the other (mostly unwritten about) url/visit style which does allow modal dialog like control . My sample ytm.rb at http://walkabout.mvmanila.com/public/share/ytm.rb shows this style of Shoes programming (you'll need http://walkabout.mvmanila.com/public/share/ytmsec.csv
ytmsec.csv to run the code, you might need the icon too).
An IRB facility does need that kind of modal control and inspection into Shoes.apps (kind of like gdb has to control its apps and threads and set values in the target. Perhaps your irb could be written in that style and if you need some api's into Shoes internals we can write them. Just a suggestion.
from shoes3.
The code seems to be accommodating on the surface but clearly not working to manage multiple Shoes apps. One oddities in https://github.com/Shoes3/shoes3/blob/master/shoes/app.c#L80 is the usage of rb_ary_dup in shoes_apps_get, which seems like a very bad idea. Also, shoes_app_new indeed pushes the app into the array.
It might be necessary to gdb this one because even though the object is listed, some of its methods are not available. It is possible to add slots and elements to a window but not read it without previously defining local variables (such as in my IRB turtorial). I did test without rb_ary_dup on Loose Shoes but without success. Accessing contents of Shoes.APPS[0] from a second window still generates an undefined method:
Error in <unknown> line 0 | 2015-01-28 11:18:41 -0500
undefined method `contents' for (Shoes::Types::App "Shoes")
contents_simple.rb:12:in `method_missing'
contents_simple.rb:12:in `block in <main>'
eval:1:in `instance_eval'
eval:1:in `block in <main>'
-e:1:in `call'
You very well understand what I ought to do with IRB. Adding a special API will certainly work but it doesn't fix the core problem. Proper support within Shoes would most certainly make IRB an amazingly useful tool but also it would allow multiple windows applications to exist, such as what once was Gimp.
from shoes3.
Investigation reveals that Shoes should properly support multiple apps. The reason the contents is not available outside its scope is that Shoes::Types::App is not related to Shoes::Types::Canvas in any way.
It is however unclear why the following code snippet will display the contents. Canvas may be mixin in some way. Using Shoes IRB will not display the contents (directly, using put or info). Also, info top
within a Shoes.app crashes Shoes on Windows — top would be a Canvas method.
Shoes.app {
para "Check Shoes console (alt-/)"
info self.class
info contents
info (self.class.instance_methods - Object.class.instance_methods).sort
}
REFERENCES
https://github.com/Shoes3/shoes3/blob/master/shoes/ruby.c#L4419 (Shoes::Types::App)
https://github.com/Shoes3/shoes3/blob/master/shoes/ruby.c#L4370 (Shoes::Types::Canvas)
from shoes3.
The clues are in ruby.c lines:4364 through 4394.
from shoes3.
The clues are in ruby.c lines:4364 through 4394.
Funny enough, on line 4392 there is cShoes = rb_define_class("Shoes", cCanvas);
. Shoes is a Canvas and Shoes::Types::App is not. How would you fix this?
I did try earlier to set the parent class of cApp to cCanvas but Shoes crashed (segfault, shoes.rb:152) before displaying the splash screen. The two following wouldn't work.
cApp = rb_define_class_under(cTypes, "App", cCanvas);
cApp = rb_define_class("App", cCanvas);
rb_include_module(cApp, cTypes);
rb_define_alloc_func(cApp, shoes_app_alloc);
from shoes3.
For a maintenance release, I wouldn't fix it ;^) This code and the manipulation of self is what makes Shoes unique (and confusing). As you've discovered, modifying stuff here almost always results in unintended behavior.
from shoes3.
Come on, we have already triumphed over a few "couldn't, wouldn't fix". :)
from shoes3.
compares the lists produced by
Shoes.app {
info Shoes::included_modules
info Shoes::instance_methods
info Shoes::Types::included_modules
info Shoes::Types::instance_methods
info Shoes::Types::App::instance_methods
info self.class
}
from shoes3.
Updated your code for clarity in the output:
Shoes.app {
info Shoes::included_modules
info (Shoes::instance_methods - Object.instance_methods).sort
info Shoes::Types::included_modules
info (Shoes::Types::instance_methods - Object.instance_methods).sort
info (Shoes::Types::App::instance_methods - Object.instance_methods).sort
info self.class
}
from shoes3.
I can guess _why rb_ary_dup was used. If Window-1 gets a list of APPS[] there is no current way that Windows-1 knows that Windows-2 spawned a half dozen windows and closed 3 of them. Or that Windows-3 (IRB for example) is poking inside Windows-1 and closed a fourth windows from there.
APPS is only an [array] of Apps/Windows/Alerts it knows about at the time it is queried. For introspection we really need a dynamic tree structure of windows at that level in the tree and ways to move up, down, left and right in the tree node. Not so simple for anyone and very not backwards compatible but that's OK, IMO.
We have a data structure problem with APPS[] and we will need some hashes or nested arrays or both. For example APPS[] could return the( flat) array of all the windows it knows about at the time. as it does now for backwards compatibility. Shoes.AppTree (.e.g) could return a dynamic list of list or list of hashes or ....
Window titles cannot be use as a hash key since a scrip(s)t can change those. A global C var may already exist for counting windows that can be use to create keys or we can create one. I'm only exploring the idea. Might be a hell of lot of 'C' code to modify and app issues will bite you in the ass.
Thoughts?
from shoes3.
Before I start modifying anything, it's good to explore how this corner of Shoes works and since I'm not particularly knowledgeable with meta programming and the Shoes core class arrangement I wrote a program to explore it. https://gist.github.com/ccoupe/95e095cbb749ba7c5006 It's Shoes so all the windows stack on top so you have to spread them out manually. Ugly.
It demonstrates that one can manipulate other Shoes windows from Shoes. Not easily because you have to instance_eval to get the binding correct and string escaping can be horrendous. However for this bug report, you can do it.
To use eval(string, TOPLEVEL_BiNDING) as IRB (and others) like to do is a problem unless Shoes/irb can switch (+save/restore) the binding. It could do that I think but it would be ugly, hackish, and prone to breakage. But I'm not very clever so perhaps someone else can do better.
from shoes3.
Turns out there is an existing App.slot method documented (by @passenger94 ?) " as
no idea what this does". app.slot.contents does appear to return canvas.contents. It's at app.c:161
I would prefer the name to be 'slots' but for compatibility reasons I will dup the tiny bit of code and rename it to slots and document slots.
And I may have found a good test case for when Shoes doesn't alway default to flow layout - a bug that has bothered me forever.
@backorder' original test script has been modified to add a start block because not everything is realized at the instantly and use slot.contents.
@app = Shoes.app {
s = stack { para "stack paragraph" }
para "paragraph"
info "contents: #{contents}"
info "Shoes.APPS[0].contents: #{Shoes.APPS[0].slot.contents}"
info "stack contents #{s.contents}"
Shoes.app {
info "Shoes.app(2)>>Shoes.APPS: #{Shoes.APPS}"
begin
info "Shoes.app(2)>>Shoes.APPS[0].contents: #{Shoes.APPS[0].slot.contents}"
rescue Exception => e
msg = e.backtrace.join("\n")
error "Shoes.app(2)>>Shoes.APPS[0]:\n#{e.message}\n#{msg}"
end
}
}
Shoes.app {
flow { para "flow paragraph" }
info "Shoes.app(3)>>Shoes.APPS[1].contents: #{Shoes.APPS[1].slot.contents}"
start do
begin
info "Shoes.app(3)>>Shoes.APPS: #{Shoes.APPS.inspect}"
rescue Exception => e
msg = e.backtrace.join("\n")
error "Shoes.app(2)>>Shoes.APPS:\n#{e.message}\n#{msg}"
end
begin
info "Shoes.app(3)>>Shoes.APPS[0].contents: #{Shoes.APPS[0].slot.contents}"
rescue Exception => e
msg = e.backtrace.join("\n")
error "Shoes.app(2)>>Shoes.APPS[0]:\n#{e.message}\n#{msg}"
end
end
}
Shoes.show_log
Also you guys should join the new mailing list even if you just want to lurk.
from shoes3.
Seems like it is working as it should. It does feel a bit overkill to have to used a slot method rather than just APPS. Changing APPS to reflect slot behaviour might need much work. This technique using slot on APPS should be documented in the manual if no other steps are taken on this issue here. Excellent work, @ccoupe!
from shoes3.
It's definitely requires a long wiki article about how to poke around inside the DSL. The start() method was also critical in the above example because that's how things work. The manual has been updated for 3.2.25
from shoes3.
Folks might be interested in the wiki article: https://github.com/Shoes3/shoes3/wiki/Poking-in-Shoes.app which adds a button in another window using the methods discovered above.
from shoes3.
This is a very good wiki article. Shoes is getting gradually demystified.
from shoes3.
Related Issues (20)
- 0xc000007b error when trying to run merged shoes exe HOT 2
- Touchscreen scrolling by dragging content HOT 14
- Packaging with an icon causes invalid bit count HOT 2
- Cannot load ZIP gem under certain conditions HOT 42
- Windows 7 mouse offset on 3.3.7 HOT 5
- Image is disappearing upon setting its path back to the original path HOT 4
- Progress bar fractions HOT 2
- Button colors HOT 2
- Image Clearing in Shoes 3 HOT 2
- Window resize HOT 4
- Menu trim for windows HOT 2
- Video player becomes transparent on sides after playing a video file HOT 7
- Iframes in app? HOT 2
- keyup and keydown not working on masOs HOT 3
- Text styles in buttons HOT 4
- Display unicode emoji in UI HOT 6
- icon HOT 9
- install old version of a gem? HOT 2
- download link to mac version offline HOT 15
- Possible logic error in code HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from shoes3.