librelist archives

« back to archive

Focus and event questions!

Focus and event questions!

From:
Saverio
Date:
2014-08-19 @ 11:57
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Hello!<br>
    <br>
    I have two questions.<br>
    <br>
    First, I can't get to focus even on a trivial app:<br>
    <br>
      Shoes.app do<br>
        @stack = stack do<br>
          @edit_line = edit_line<br>
          @edit_line.focus<br>
        end<br>
      end<br>
    <br>
    (ignore the structure, I've extracted it from some code).<br>
    <br>
    Am I missing something?<br>
    <br>
    Second, this is more complicated. I have an app where I have to
    detect the Enter keypress. The app is essentially a poor man's
    spotlight (I'll refer to it as "PMS" (hehehe)).<br>
    <br>
    I fill the box (EditLine), and PMS automatically appends some
    Button[s] (since it's a poor man's application).<br>
    <br>
    Now, the problem is this: assuming the user is on the EditLine, if
    he clicks enter, I want PMS to execute the first entry. This
    execution is not a problem - I define the :keypress listener at the
    app level, and catch "\n".<br>
    The problem is that when the user is on a Button and taps Enter, two
    events will be generated, one for keypress, and one for the Button
    click.<br>
    I can't find an obvious solution, and the non-obvious is a horrible
    hack, that is, queue the requests in a Thread which sleeps for a
    short time, so that it can detects if there are two calls.<br>
    <br>
    This is the relevant code:<br>
    <br>
      def execute_entry( entry )<br>
        if @execution_thread.nil?<br>
          @execution_thread = Thread.new do<br>
            Thread.current[ :entry ] = entry<br>
    <br>
            sleep EXECUTION_DELAY<br>
    <br>
            puts Thread.current[ :entry ]<br>
    <br>
            exit<br>
          end<br>
        else<br>
          @execution_thread[ :entry ] = entry<br>
          @execution_thread.join<br>
        end<br>
      end<br>
    <br>
    Shoes.app do<br>
        @stack = stack do<br>
          @edit_line = edit_line<br>
    <br>
          @edit_line.change do<br>
            clean_elements( @stack )<br>
    <br>
            current_entries = filter_entries( @edit_line.text )<br>
    <br>
            add_entry_elements( current_entries, @stack )<br>
          end<br>
    <br>
          keypress do | key |<br>
            # There is quite a problem here. The keypress event is not
    available on the elements,<br>
            # but on the app, so that when enter is pressed, if a button
    is highlighted we get<br>
            # two events.<br>
            # In addition to that, apparently we can't even get which
    element is highlighted.<br>
            #<br>
            # We work this around by delaying the execution, so that if
    a button is clicked, it<br>
            # overrides the keypress callback.<br>
            #<br>
            if key == "\n"<br>
              current_entries = filter_entries( @edit_line.text )<br>
    <br>
              if current_entries.size >= 1<br>
               execute_entry( current_entries[ 0 ] )<br>
             end<br>
            end<br>
          end<br>
        end<br>
      end<br>
    <br>
    Am I missing something obvious here, as well?<br>
    <br>
    Many thanks.<br>
    Saverio<br>
    <br>
    ps. "Arne sent me" :-D<br>
  </body>
</html>

Re: [shoes] Focus and event questions!

From:
Kc Erb
Date:
2014-08-19 @ 13:01
Hi Saverio,

As for your first question, focus is broken right now :(
https://github.com/shoes/shoes4/issues/610

I'm not sure I understand your second question though. Are you looking for
a way to catch the "\n" keypress when focus is on a button without
triggering the button?


On Tue, Aug 19, 2014 at 5:57 AM, Saverio <saverio.pub2@gmail.com> wrote:

> <html>
>   <head>
>     <meta http-equiv="content-type" content="text/html; charset=utf-8">
>   </head>
>   <body bgcolor="#FFFFFF" text="#000000">
>     Hello!<br>
>     <br>
>     I have two questions.<br>
>     <br>
>     First, I can't get to focus even on a trivial app:<br>
>     <br>
>       Shoes.app do<br>
>         @stack = stack do<br>
>           @edit_line = edit_line<br>
>           @edit_line.focus<br>
>         end<br>
>       end<br>
>     <br>
>     (ignore the structure, I've extracted it from some code).<br>
>     <br>
>     Am I missing something?<br>
>     <br>
>     Second, this is more complicated. I have an app where I have to
>     detect the Enter keypress. The app is essentially a poor man's
>     spotlight (I'll refer to it as "PMS" (hehehe)).<br>
>     <br>
>     I fill the box (EditLine), and PMS automatically appends some
>     Button[s] (since it's a poor man's application).<br>
>     <br>
>     Now, the problem is this: assuming the user is on the EditLine, if
>     he clicks enter, I want PMS to execute the first entry. This
>     execution is not a problem - I define the :keypress listener at the
>     app level, and catch "\n".<br>
>     The problem is that when the user is on a Button and taps Enter, two
>     events will be generated, one for keypress, and one for the Button
>     click.<br>
>     I can't find an obvious solution, and the non-obvious is a horrible
>     hack, that is, queue the requests in a Thread which sleeps for a
>     short time, so that it can detects if there are two calls.<br>
>     <br>
>     This is the relevant code:<br>
>     <br>
>       def execute_entry( entry )<br>
>         if @execution_thread.nil?<br>
>           @execution_thread = Thread.new do<br>
>             Thread.current[ :entry ] = entry<br>
>     <br>
>             sleep EXECUTION_DELAY<br>
>     <br>
>             puts Thread.current[ :entry ]<br>
>     <br>
>             exit<br>
>           end<br>
>         else<br>
>           @execution_thread[ :entry ] = entry<br>
>           @execution_thread.join<br>
>         end<br>
>       end<br>
>     <br>
>     Shoes.app do<br>
>         @stack = stack do<br>
>           @edit_line = edit_line<br>
>     <br>
>           @edit_line.change do<br>
>             clean_elements( @stack )<br>
>     <br>
>             current_entries = filter_entries( @edit_line.text )<br>
>     <br>
>             add_entry_elements( current_entries, @stack )<br>
>           end<br>
>     <br>
>           keypress do | key |<br>
>             # There is quite a problem here. The keypress event is not
>     available on the elements,<br>
>             # but on the app, so that when enter is pressed, if a button
>     is highlighted we get<br>
>             # two events.<br>
>             # In addition to that, apparently we can't even get which
>     element is highlighted.<br>
>             #<br>
>             # We work this around by delaying the execution, so that if
>     a button is clicked, it<br>
>             # overrides the keypress callback.<br>
>             #<br>
>             if key == "\n"<br>
>               current_entries = filter_entries( @edit_line.text )<br>
>     <br>
>               if current_entries.size >= 1<br>
>                execute_entry( current_entries[ 0 ] )<br>
>              end<br>
>             end<br>
>           end<br>
>         end<br>
>       end<br>
>     <br>
>     Am I missing something obvious here, as well?<br>
>     <br>
>     Many thanks.<br>
>     Saverio<br>
>     <br>
>     ps. "Arne sent me" :-D<br>
>   </body>
> </html>
>



-- 
 "If there is an exception to every rule, then every rule must have at
least one exception; the exception to this one being that it has no
exception."

Re: [shoes] Focus and event questions!

From:
Saverio
Date:
2014-08-19 @ 15:44
Regarding the second, yes. I'll try to be a bit more clear.

You have, say, an editlist and two butt(on)s:

+-----------+
+ edit_list+
+-----------+
+ butt1    +
+-----------+
+ butt2    +
+-----------+

the expectation is the following:

- if I press enter on edit_list, a certain action is taken, say, action1
- if I press enter on button1, another action is taken, say, action2

(note that this is a simplified model of the logic).

now, I can't directly listen to enter using EditList#change(), because 
no events are fired on such key(press), so I have to listen to 
App#keypress().

the problem with this approach (which can be worked around in a ahem... 
non-pretty way) is that pressing enter when the button is in focus, will 
cause two events two be fired: one for the button click, and the other 
for the enter keypress.

this is not desirable, because in this case, se would expect only the 
button event to be fired.

more in general, GUI frameworks have per-element listeners, but in this 
case, we don't [have keypress on EditList], so I was wondering if there 
is a clean way of circumventing this.

Thanks!
Saverio

On 19.08.2014 15:01, KC Erb wrote:
> Hi Saverio,
>
> As for your first question, focus is broken right now :(
> https://github.com/shoes/shoes4/issues/610
>
> I'm not sure I understand your second question though. Are you looking 
> for a way to catch the "\n" keypress when focus is on a button without 
> triggering the button?
>
>
> On Tue, Aug 19, 2014 at 5:57 AM, Saverio <saverio.pub2@gmail.com 
> <mailto:saverio.pub2@gmail.com>> wrote:
>
>     <html>
>       <head>
>         <meta http-equiv="content-type" content="text/html;
>     charset=utf-8">
>       </head>
>       <body bgcolor="#FFFFFF" text="#000000">
>         Hello!<br>
>         <br>
>         I have two questions.<br>
>         <br>
>         First, I can't get to focus even on a trivial app:<br>
>         <br>
>           Shoes.app do<br>
>             @stack = stack do<br>
>               @edit_line = edit_line<br>
>               @edit_line.focus<br>
>             end<br>
>           end<br>
>         <br>
>         (ignore the structure, I've extracted it from some code).<br>
>         <br>
>         Am I missing something?<br>
>         <br>
>         Second, this is more complicated. I have an app where I have to
>         detect the Enter keypress. The app is essentially a poor man's
>         spotlight (I'll refer to it as "PMS" (hehehe)).<br>
>         <br>
>         I fill the box (EditLine), and PMS automatically appends some
>         Button[s] (since it's a poor man's application).<br>
>         <br>
>         Now, the problem is this: assuming the user is on the EditLine, if
>         he clicks enter, I want PMS to execute the first entry. This
>         execution is not a problem - I define the :keypress listener
>     at the
>         app level, and catch "\n".<br>
>         The problem is that when the user is on a Button and taps
>     Enter, two
>         events will be generated, one for keypress, and one for the Button
>         click.<br>
>         I can't find an obvious solution, and the non-obvious is a
>     horrible
>         hack, that is, queue the requests in a Thread which sleeps for a
>         short time, so that it can detects if there are two calls.<br>
>         <br>
>         This is the relevant code:<br>
>         <br>
>           def execute_entry( entry )<br>
>             if @execution_thread.nil?<br>
>               @execution_thread = Thread.new do<br>
>                 Thread.current[ :entry ] = entry<br>
>         <br>
>                 sleep EXECUTION_DELAY<br>
>         <br>
>                 puts Thread.current[ :entry ]<br>
>         <br>
>                 exit<br>
>               end<br>
>             else<br>
>               @execution_thread[ :entry ] = entry<br>
>               @execution_thread.join<br>
>             end<br>
>           end<br>
>         <br>
>         Shoes.app do<br>
>             @stack = stack do<br>
>               @edit_line = edit_line<br>
>         <br>
>               @edit_line.change do<br>
>                 clean_elements( @stack )<br>
>         <br>
>                 current_entries = filter_entries( @edit_line.text )<br>
>         <br>
>                 add_entry_elements( current_entries, @stack )<br>
>               end<br>
>         <br>
>               keypress do | key |<br>
>                 # There is quite a problem here. The keypress event is not
>         available on the elements,<br>
>                 # but on the app, so that when enter is pressed, if a
>     button
>         is highlighted we get<br>
>                 # two events.<br>
>                 # In addition to that, apparently we can't even get which
>         element is highlighted.<br>
>                 #<br>
>                 # We work this around by delaying the execution, so
>     that if
>         a button is clicked, it<br>
>                 # overrides the keypress callback.<br>
>                 #<br>
>                 if key == "\n"<br>
>                   current_entries = filter_entries( @edit_line.text )<br>
>         <br>
>                   if current_entries.size >= 1<br>
>                    execute_entry( current_entries[ 0 ] )<br>
>                  end<br>
>                 end<br>
>               end<br>
>             end<br>
>           end<br>
>         <br>
>         Am I missing something obvious here, as well?<br>
>         <br>
>         Many thanks.<br>
>         Saverio<br>
>         <br>
>         ps. "Arne sent me" :-D<br>
>       </body>
>     </html>
>
>
>
>
> -- 
>  "If there is an exception to every rule, then every rule must have at 
> least one exception; the exception to this one being that it has no 
> exception."

Re: [shoes] Focus and event questions!

From:
Kc Erb
Date:
2014-08-19 @ 18:19
>
> now, I can't directly listen to enter using EditList#change(), because
> no events are fired on such key(press), so I have to listen to
> App#keypress().


I'm not sure what you mean by "no events are fired on such key(press)" but
playing around with this I am finding that the change block isn't called
when the enter key is used. I'm not sure why that is, so I've opened up a
discussion about it on github >> #860
<https://github.com/shoes/shoes4/issues/860>

Until that gets fixed your current hack might be the best way . . . but
other Shoes-ers out there might have a better idea!

Until that gets fixed can you use some kind of alternative character. For
example, using "/" here's something I threw together:

gist <https://gist.github.com/KCErb/5923b2f85c2664c02022>


Hope that helps!

-KC


On Tue, Aug 19, 2014 at 9:44 AM, Saverio <saverio.pub2@gmail.com> wrote:

> Regarding the second, yes. I'll try to be a bit more clear.
>
> You have, say, an editlist and two butt(on)s:
>
> +-----------+
> + edit_list+
> +-----------+
> + butt1    +
> +-----------+
> + butt2    +
> +-----------+
>
> the expectation is the following:
>
> - if I press enter on edit_list, a certain action is taken, say, action1
> - if I press enter on button1, another action is taken, say, action2
>
> (note that this is a simplified model of the logic).
>
> now, I can't directly listen to enter using EditList#change(), because
> no events are fired on such key(press), so I have to listen to
> App#keypress().
>
> the problem with this approach (which can be worked around in a ahem...
> non-pretty way) is that pressing enter when the button is in focus, will
> cause two events two be fired: one for the button click, and the other
> for the enter keypress.
>
> this is not desirable, because in this case, se would expect only the
> button event to be fired.
>
> more in general, GUI frameworks have per-element listeners, but in this
> case, we don't [have keypress on EditList], so I was wondering if there
> is a clean way of circumventing this.
>
> Thanks!
> Saverio
>
> On 19.08.2014 15:01, KC Erb wrote:
> > Hi Saverio,
> >
> > As for your first question, focus is broken right now :(
> > https://github.com/shoes/shoes4/issues/610
> >
> > I'm not sure I understand your second question though. Are you looking
> > for a way to catch the "\n" keypress when focus is on a button without
> > triggering the button?
> >
> >
> > On Tue, Aug 19, 2014 at 5:57 AM, Saverio <saverio.pub2@gmail.com
> > <mailto:saverio.pub2@gmail.com>> wrote:
> >
> >     <html>
> >       <head>
> >         <meta http-equiv="content-type" content="text/html;
> >     charset=utf-8">
> >       </head>
> >       <body bgcolor="#FFFFFF" text="#000000">
> >         Hello!<br>
> >         <br>
> >         I have two questions.<br>
> >         <br>
> >         First, I can't get to focus even on a trivial app:<br>
> >         <br>
> >           Shoes.app do<br>
> >             @stack = stack do<br>
> >               @edit_line = edit_line<br>
> >               @edit_line.focus<br>
> >             end<br>
> >           end<br>
> >         <br>
> >         (ignore the structure, I've extracted it from some code).<br>
> >         <br>
> >         Am I missing something?<br>
> >         <br>
> >         Second, this is more complicated. I have an app where I have to
> >         detect the Enter keypress. The app is essentially a poor man's
> >         spotlight (I'll refer to it as "PMS" (hehehe)).<br>
> >         <br>
> >         I fill the box (EditLine), and PMS automatically appends some
> >         Button[s] (since it's a poor man's application).<br>
> >         <br>
> >         Now, the problem is this: assuming the user is on the EditLine,
> if
> >         he clicks enter, I want PMS to execute the first entry. This
> >         execution is not a problem - I define the :keypress listener
> >     at the
> >         app level, and catch "\n".<br>
> >         The problem is that when the user is on a Button and taps
> >     Enter, two
> >         events will be generated, one for keypress, and one for the
> Button
> >         click.<br>
> >         I can't find an obvious solution, and the non-obvious is a
> >     horrible
> >         hack, that is, queue the requests in a Thread which sleeps for a
> >         short time, so that it can detects if there are two calls.<br>
> >         <br>
> >         This is the relevant code:<br>
> >         <br>
> >           def execute_entry( entry )<br>
> >             if @execution_thread.nil?<br>
> >               @execution_thread = Thread.new do<br>
> >                 Thread.current[ :entry ] = entry<br>
> >         <br>
> >                 sleep EXECUTION_DELAY<br>
> >         <br>
> >                 puts Thread.current[ :entry ]<br>
> >         <br>
> >                 exit<br>
> >               end<br>
> >             else<br>
> >               @execution_thread[ :entry ] = entry<br>
> >               @execution_thread.join<br>
> >             end<br>
> >           end<br>
> >         <br>
> >         Shoes.app do<br>
> >             @stack = stack do<br>
> >               @edit_line = edit_line<br>
> >         <br>
> >               @edit_line.change do<br>
> >                 clean_elements( @stack )<br>
> >         <br>
> >                 current_entries = filter_entries( @edit_line.text )<br>
> >         <br>
> >                 add_entry_elements( current_entries, @stack )<br>
> >               end<br>
> >         <br>
> >               keypress do | key |<br>
> >                 # There is quite a problem here. The keypress event is
> not
> >         available on the elements,<br>
> >                 # but on the app, so that when enter is pressed, if a
> >     button
> >         is highlighted we get<br>
> >                 # two events.<br>
> >                 # In addition to that, apparently we can't even get which
> >         element is highlighted.<br>
> >                 #<br>
> >                 # We work this around by delaying the execution, so
> >     that if
> >         a button is clicked, it<br>
> >                 # overrides the keypress callback.<br>
> >                 #<br>
> >                 if key == "\n"<br>
> >                   current_entries = filter_entries( @edit_line.text )<br>
> >         <br>
> >                   if current_entries.size >= 1<br>
> >                    execute_entry( current_entries[ 0 ] )<br>
> >                  end<br>
> >                 end<br>
> >               end<br>
> >             end<br>
> >           end<br>
> >         <br>
> >         Am I missing something obvious here, as well?<br>
> >         <br>
> >         Many thanks.<br>
> >         Saverio<br>
> >         <br>
> >         ps. "Arne sent me" :-D<br>
> >       </body>
> >     </html>
> >
> >
> >
> >
> > --
> >  "If there is an exception to every rule, then every rule must have at
> > least one exception; the exception to this one being that it has no
> > exception."
>
>


-- 
 "If there is an exception to every rule, then every rule must have at
least one exception; the exception to this one being that it has no
exception."