FLTK logo

Re: [fltk.general] What is the right way to do these shortcuts?

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: What is the right way to do these shortcuts? Greg Ercolano May 12, 2021  
 


On 5/12/21 3:13 AM, Dave Jordan wrote:
This method works except for 1 UI flaw and 1 obvious inefficiency, both of which are described under switch(e)
I know can't be doing it quite right. I have tried test_shortcut; no idea whether it's appropriate or
what is the correct usage.

All the shortcuts keys are created here

class Appmenu : public Fl_Menu_Bar {
public:
Appmenu(App *app) : Fl_Menu_Bar(... dims ...) {
add("menu/save", FL_CTRL + 's', save_cb, app); // app is the main and only application window

    Hmm, I must be missing something.

    IN that one add("menu/save"..) line, FLTK has been told to invoke the save_cb() method
    if either the menu -> save is picked, or if someone hits Ctrl-S.

   
So you're done right there, nothing else to do.

    Unless you're trying to define other global shortcuts not defined in the menu..?
    In which case you'd create a handle() method that looks for FL_SHORTCUT
    events, and then look at the key combo being pressed to see if it's what you want, e.g.

        case FL_SHORTCUT:
            if ( Fl::event_key() == 'a' && Fl::event_state() & FL_Alt )   // SHIFT-a

    I'd say look at the docs on event handling first:
    https://www.fltk.org/doc-1.4/events.html

    Especially read about FL_FOCUS/UNFOCUS and FL_ENTER/LEAVE to be sure
    you're using the right ones.

    Some comments on the handle() code you posted..

    1) You shouldn't need to do this:

           int handle(int e) { return brd_handle(this, e); }
           static int brd_handle(Cell *cell, int e);

       You don't have to work with 'this' -- handle() is not a static callback,
       it's a virtual method you're overriding, and it's invoked by FLTK for you
       whenever an event is delivered in the context of the class.

    3) Only define a handle() method for your class if you need one.

       The default event handler in the base class (Fl_Box in this case) will handle the default behavior.

    4) If you define a handle() method, be sure to call the base class's handle() method
       so it can still see the events. If you don't, you'll be eclipsing all events from the base class,
       which is usually bad. In the below rewrite of your handle() method, I call Fl_Box::handle(e)
       at the top and keep its return value in ret, so any events that IT handles but you don't
       return the proper 0 or 1 value out of the handle() method so FLTK can process the event properly.
      
    5) Only check for events you need to use -- don't do anything with other events.
       For instance, don't try to add a case statement for every event you aren't
       dealing with, you simply return the base class's return value.

    Here's what I think your handle() method should probably look like, if you need one at all:

int Cell::handle(int e) {
    int ret = Fl_Box::handle(e);
    // IMPORTANT: let box's own handle() method get access to the event and keep track of its return value
                                    // If you don't do this, you'll be eclipsing events from the base class Fl_Box, which is generally bad
                                    // unless you know what
you're doing..

    switch (e) {
                    // now check for events you want to handle, /ignore/ the rest
        case FL_FOCUS:
           
// do your stuff here when the widget takes focus
            ret = 1;               
// tells FLTK you're interested in FOCUS events -- see docs on FL_FOCUS for specifics
            break;
        case FL_UNFOCUS:
           
// do your stuff here when the widget goes out of focus
            ret = 1;
            break;
        case FL_PUSH:
           
//
            // do your stuff. You may not need to call take_focus() unless you're doing something special
            //

            if ( you_did_something_with_the_event ) ret = 1;   // do this only if you actually handled the push event, and no one else should get it
            break;
    }
    return ret;
}

    That should be it.
    Thing is, I'm not sure you need a handle() method.

    You probably don't need to do specific stuff with take_focus() and such unless you're
    doing something very special.

    Also, I'm not sure you should be doing anything with FL_FOCUS. If you want the cell
    to light up when you hover over it, use FL_ENTER and FL_LEAVE instead, that might be
    what you want -- I'm not sure. See the docs at the above link and read what it says
    FL_ENTER/FL_LEAVE do vs FL_FOCUS/FL_UNFOCUS.

    Focus is mainly for keyboard oriented widgets, like if you were implementing a text input
    widget or something, and want to be able to take focus with a click or keyboard navigation
    of focus using TAB, etc.

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/845110bf-a745-cd92-9345-f3bc67e9db9e%40seriss.com.
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.