Re: [shoes] Multimodal apps in Shoes
- From:
- Cecil Coupe
- Date:
- 2012-02-09 @ 07:28
Hi,
I think there are several ways to do what you want - multiple modal
screens. It highly depends on your application and users. There are no
best practices. I would suggest a top level guided menu screen using
url index/links/visit "Click for part 1, click for part 2" I would
**not** call part2 from inside part1. What if you later need part 3 or
1.5?
I would call part1 or part2 depending on what part0 (your
menu/controller) thinks is the next step. Said menu screen can impose
Modality as it sees fit by. Hacketyhack is a large Shoes program with
many lessons in dealing with modality and multiple sub-screens. A big
gulp to be sure but you only need the design or template to see what is
possible
--Cecil
On Wed, 2012-02-08 at 18:28 -0800, Jesse Edelstein wrote:
> Hi all. I've gotten into Shoes recently, as I'm a cognitive
> psychologist and it seems to be a practical way to code up
> experiments. I've managed to answer most of my questions through
> searching and trial-and-error (did you know Shoes has a pretty
> functional fullscreen mode?) but I'm still pretty confused about best
> practices for writing multimodal programs.
>
> What I mean specifically is programs that have one UI, then move to a
> different UI (based on time passing, or user input, or whatever), then
> move on to another one, according to however I've programmed it.
> Ideally you should be able to move between different modes in an
> arbitrary order, so the methods for each mode should be able to set up
> a new interface and then remove it before returning.
>
> My question is: what's the natural way to do this in Shoes? My code
> currently looks like this:
>
> def first_task
> # UI setup
> # task
> # UI removal
> second_task
> end
>
> def second_task
> # as in first task
> end
>
> Shoes.app do
> # setup
> first_task
> end
>
> This does not work well, and it would still be a really hairy way to
> design the program even if it worked properly. For instance, animate()
> loops don't seem to close when a new method is called, so they keep
> running in the background, giving errors if the objects they control
> have been deleted. So what's the more appropriate way to set up a
> multi-mode program?
>
> Another question: How do I get Shoes to pop up an alert when an
> unhandled error is encountered, instead of piping it to the console
> (which I never remember to check)?
>
> Thanks, Jesse
Re: Multimodal apps in Shoes
- From:
- Jesse Edelstein
- Date:
- 2012-02-09 @ 06:23
To make my question
(http://librelist.com/browser//shoes/2012/2/9/multimodal-apps-in-shoes/)
clearer, let me give a minimal example. I'd like to write multimodal
apps in the most obvious way: a series of methods for each mode, with
each one called in sequence by the main Shoes object. But this doesn't
work as advertised; instead everything seems to display at once, even
if it's supposed to wait for user input or something before
continuing. For example:
Shoes.app :width => 800, :height => 500 do
def present_instructions (instructions)
text = stack {para instructions}
keypress do |key|
if key == " " then
text.remove
break
end
end
end
def main_task
stack do
@textdisplay = para "Here's the main task. Enter your answers below."
@freeresponse = edit_box :width => 400, :height => 200
end
end
present_instructions('Instructions go here. Press space to continue')
main_task()
end
Re: [shoes] Re: Multimodal apps in Shoes
- From:
- ashbb
- Date:
- 2012-02-09 @ 14:59
Hi Jesse, Cecil, J and folks,
As already Cecil and J mentioned, there are several ways. ;-)
I tried to edit Jesse's code a little bit.
But I'm not sure this code suits your taste. ;-)
Shoes.app :width => 800, :height => 500 do
present_instructions = proc do |instructions|
para instructions
end
main_task = proc do
@textdisplay = para "Here's the main task. Enter your answers below."
@freeresponse = edit_box :width => 400, :height => 200
end
tasks = []
tasks << present_instructions
tasks << main_task
slot = stack{tasks[0]['Instructions go here. Press space to continue']}
keypress do |key|
if key == ' ' and !@stop
slot.clear{tasks[1][]}
@stop = true
end
end
end
ashbb
Re: [shoes] Re: Multimodal apps in Shoes
- From:
- Cecil Coupe
- Date:
- 2012-02-09 @ 08:38
See the last example of
http://stackoverflow.com/questions/732967/while-loop-in-ruby-shoes-gui-toolkit
to observe url and visit. It's not in the manual and I don't do it often enough
to remember the rules. I think you have subclass Shoe.
Re: [shoes] Re: Multimodal apps in Shoes
- From:
- Tobias Pfeiffer
- Date:
- 2012-02-09 @ 08:52
url leads to a segfault for me in some easy cases (there is a bug report
somewhere).
I've extracted the part handling tabs from HacketyHack and used it in
infoes, I want to try to use the same code in a new app I write and if
that works out I'll try to get it into main shoes or write some kind of
gem. I believe this could be what you are looking for.
For the curios, code for the tab in general is there:
https://github.com/PragTob/infoes/blob/master/lib/infoes/side_tab.rb
A little example tab:
https://github.com/PragTob/infoes/blob/master/lib/infoes/tabs/home.rb
(you gotta subclass side_tab)
And here is how you open those tabs:
https://github.com/PragTob/infoes/blob/master/lib/infoes.rb#L47-62 (for
a main shoes version/gem I'd likely move this to be class methods of
SideTab)
Still probably needs some work but useful though.
Tobi
On 02/09/2012 09:38 AM, Cecil Coupe wrote:
> See the last example of
> http://stackoverflow.com/questions/732967/while-loop-in-ruby-shoes-gui-toolkit
> to observe url and visit. It's not in the manual and I don't do it often enough
> to remember the rules. I think you have subclass Shoe.
>
Re: [shoes] Re: Multimodal apps in Shoes
- From:
- J. Kaiden
- Date:
- 2012-02-09 @ 11:24
hi Jesse,
you could take a look at the simple notebook widget here:
https://github.com/lljk/shoes-stuff/blob/master/notebook_widget/notebook_widget_example.rb
i don't have the time right now (got to head off to work, bummer...) but
i think this could be pretty easily modified to do what you want.
right now you change pages by clicking on the button (@tab) at the top of
the main window that represents the page you want to see. if you added a
`show_page(name)` method to the NoteBook widget class that was similar to
the `@tab.click{}` block (and then perhaps removed the #click call so
people can't change pages by themselves,) you could change pages based on
user input rather than button clicks...
hth,
- j
On Thu, Feb 9, 2012 at 8:52 AM, Tobias Pfeiffer <
tobias.pfeiffer@student.hpi.uni-potsdam.de> wrote:
> url leads to a segfault for me in some easy cases (there is a bug report
> somewhere).
>
> I've extracted the part handling tabs from HacketyHack and used it in
> infoes, I want to try to use the same code in a new app I write and if
> that works out I'll try to get it into main shoes or write some kind of
> gem. I believe this could be what you are looking for.
>
> For the curios, code for the tab in general is there:
> https://github.com/PragTob/infoes/blob/master/lib/infoes/side_tab.rb
> A little example tab:
> https://github.com/PragTob/infoes/blob/master/lib/infoes/tabs/home.rb
> (you gotta subclass side_tab)
>
> And here is how you open those tabs:
> https://github.com/PragTob/infoes/blob/master/lib/infoes.rb#L47-62 (for
> a main shoes version/gem I'd likely move this to be class methods of
> SideTab)
>
> Still probably needs some work but useful though.
>
> Tobi
>
> On 02/09/2012 09:38 AM, Cecil Coupe wrote:
> > See the last example of
> >
> http://stackoverflow.com/questions/732967/while-loop-in-ruby-shoes-gui-toolkit
> > to observe url and visit. It's not in the manual and I don't do it often
> enough
> > to remember the rules. I think you have subclass Shoe.
> >
>
>
Re: [shoes] Re: Multimodal apps in Shoes
- From:
- Jesse Edelstein
- Date:
- 2012-02-09 @ 14:38
Thanks for all the feedback, Cecil, Tobias, & Jake. I'm learning a lot
from all this but I haven't made too much progress yet. I'm working on
refactoring my design to make it a properly object-oriented model in
line with Infoes and that notebook example.
I'm still very unclear on how to move between program elements due to
a keypress, for instance. In my program, I display some initial
instructions, then have the user press the spacebar to advance to the
next screen. What's the sensible way to do this? My intuition is to do
it like this:
class PresentInstructions < Shoes::Widget
def initialize(instructions)
@s = stack :margin => 100 do
para instructions, :font => "Arial 36px", :stroke => white
end
@s.hide
end
def go
@s.show
# wait for user to hit space
keypress do |key|
if (key == " ")
self.stop
break #error here!
end
end
end
def stop
@s.hide
end
end
I intended to initialize my instructions objects first (following that
notebook example) and then call their #go method to make them active
when needed, assuming that go will return once the user has pressed
space. But this does not work - Ruby throws an error when I try to
break early. Am I not allowed to break out of a keypress loop? If not,
how do I stop polling for keypresses when I'm done looking for them?
Moreover, what's a working way to design this part of my app?
Thanks again for all your advice. It's nice to see that this niche
product has a good community.
Jesse
Re: [shoes] Re: Multimodal apps in Shoes
- From:
- ashbb
- Date:
- 2012-02-09 @ 15:28
Hi Jesse,
> Am I not allowed to break out of a keypress loop?
No, you can't.
> If not, how do I stop polling for keypresses when I'm done looking for
them?
The following snippet is one of the solutions. ;-)
Shoes.app do
slot = stack
keypress do |key|
unless @stop
case key
when ' '
slot.clear{para 'Your input key is space. So, stop showing input
key.'}
@stop = :stopped
else
slot.clear{para "Your input key is #{key}"}
end
end
end
end
Hope this helps,
ashbb
Re: [shoes] Multimodal apps in Shoes
- From:
- ashbb
- Date:
- 2012-02-09 @ 14:57
Hi Jesse,
Sorry, I'm late.
> I've gotten into Shoes recently
Fantastic!
> I've managed to answer most of my questions through
> searching and trial-and-error
Great!
But we love to see questions in Shoes ML.
So, thank you so much for posting your mail. :)
> (did you know Shoes has a pretty functional fullscreen mode?)
Ah, sorry. Shoes doesn't support fullscreen mode so far.
About your first question. Try out the following snippet:
module Task
def first_task
para "First UI setup\n"
p = para
a = animate 2 do |i|
p.text = "running task: #{i}"
if i > 10
a.stop
clear{second_task}
end
end
end
def second_task
para "Second UI setup\n"
p = para
a = animate 2 do |i|
p.text = "running task: #{i}"
if i > 10
a.stop
p.text = 'FIN!'
end
end
end
end
Shoes.app do
extend Task
first_task
end
About your second question. Try out this one:
Shoes.app do
begin
IO.read 'missing_file'
rescue Exception => e
alert e.message
end
end
I'm not sure that I understand your questions correctly.
But hope this helps,
ashbb
Re: [shoes] Multimodal apps in Shoes
- From:
- Steve Klabnik
- Date:
- 2012-02-09 @ 15:28
Ash,
> Ah, sorry. Shoes doesn't support fullscreen mode so far.
Actually, Shoes does have a fullscreen mode, it's just a bit buggy,
and not documented:
https://github.com/shoes/shoes/blob/24843c0a9cd1d014409c58ed06a62cff41ee83a0/shoes/native.h#L37
https://github.com/shoes/shoes/blob/24843c0a9cd1d014409c58ed06a62cff41ee83a0/shoes/app.c#L58
https://github.com/shoes/shoes/blob/8b1c84fa9cfef4a380a488212461d7e4abcf798d/shoes/native/gtk.c#L536
https://github.com/shoes/shoes/blob/8b1c84fa9cfef4a380a488212461d7e4abcf798d/shoes/native/cocoa.m#L871
https://github.com/shoes/shoes/blob/24843c0a9cd1d014409c58ed06a62cff41ee83a0/shoes/native/windows.c#L897
Re: [shoes] Multimodal apps in Shoes
- From:
- ashbb
- Date:
- 2012-02-09 @ 15:34
Hi Steve,
> Actually, Shoes does have a fullscreen mode,
Yeah, you are right. I know the code.
But,
> it's just a bit buggy
This is also true. So, I said "Shoes doesn't support". ;-)
ashbb
Re: [shoes] Multimodal apps in Shoes
- From:
- Steve Klabnik
- Date:
- 2012-02-09 @ 15:41
> This is also true. So, I said "Shoes doesn't support". ;-)
Fair enough! :)