Improved event handling code
This commit is contained in:
parent
62b4a68277
commit
7d4de8e46f
|
@ -1,5 +1,6 @@
|
||||||
2020-04-15 Markus Gans <guru.mail@muenster.de>
|
2020-04-15 Markus Gans <guru.mail@muenster.de>
|
||||||
* Better support of general arrow keys
|
* Better support of general arrow keys
|
||||||
|
* Improved event handling code
|
||||||
|
|
||||||
2020-04-13 Markus Gans <guru.mail@muenster.de>
|
2020-04-13 Markus Gans <guru.mail@muenster.de>
|
||||||
* Several small code improvements
|
* Several small code improvements
|
||||||
|
|
|
@ -130,7 +130,7 @@ int main (int argc, char* argv[])
|
||||||
|
|
||||||
// Scroll to the focused child element
|
// Scroll to the focused child element
|
||||||
finalcut::FFocusEvent cfi (finalcut::fc::ChildFocusIn_Event);
|
finalcut::FFocusEvent cfi (finalcut::fc::ChildFocusIn_Event);
|
||||||
finalcut::FApplication::queueEvent(&checkButtonGroup, &cfi);
|
app.queueEvent(&checkButtonGroup, &cfi);
|
||||||
|
|
||||||
// Create a OK button
|
// Create a OK button
|
||||||
finalcut::FButton ok("&OK", &dgl);
|
finalcut::FButton ok("&OK", &dgl);
|
||||||
|
|
|
@ -59,8 +59,6 @@ int FApplication::loop_level {0}; // event loop level
|
||||||
int FApplication::quit_code {0};
|
int FApplication::quit_code {0};
|
||||||
bool FApplication::quit_now {false};
|
bool FApplication::quit_now {false};
|
||||||
|
|
||||||
FApplication::eventQueue* FApplication::event_queue{nullptr};
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// class FApplication
|
// class FApplication
|
||||||
|
@ -100,10 +98,6 @@ FApplication::FApplication ( const int& _argc
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
FApplication::~FApplication() // destructor
|
FApplication::~FApplication() // destructor
|
||||||
{
|
{
|
||||||
if ( event_queue )
|
|
||||||
delete event_queue;
|
|
||||||
|
|
||||||
event_queue = nullptr;
|
|
||||||
app_object = nullptr;
|
app_object = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,75 +166,27 @@ void FApplication::quit()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
bool FApplication::sendEvent ( const FObject* receiver
|
bool FApplication::sendEvent (FObject* receiver, FEvent* event )
|
||||||
, const FEvent* event )
|
|
||||||
{
|
{
|
||||||
if ( quit_now || app_exit_loop || ! receiver )
|
if ( quit_now || app_exit_loop || ! receiver )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( receiver->isWidget() )
|
if ( ! isEventProcessable (receiver, event) )
|
||||||
{
|
|
||||||
const auto widget = static_cast<const FWidget*>(receiver);
|
|
||||||
|
|
||||||
if ( getModalDialogCounter() > 0 )
|
|
||||||
{
|
|
||||||
const FWidget* window;
|
|
||||||
|
|
||||||
if ( widget->isWindowWidget() )
|
|
||||||
window = widget;
|
|
||||||
else
|
|
||||||
window = FWindow::getWindowWidget(widget);
|
|
||||||
|
|
||||||
// block events for widgets in non modal windows
|
|
||||||
if ( window
|
|
||||||
&& ! window->getFlags().modal
|
|
||||||
&& ! window->isMenuWidget() )
|
|
||||||
{
|
|
||||||
switch ( uInt(event->type()) )
|
|
||||||
{
|
|
||||||
case fc::KeyPress_Event:
|
|
||||||
case fc::KeyUp_Event:
|
|
||||||
case fc::KeyDown_Event:
|
|
||||||
case fc::MouseDown_Event:
|
|
||||||
case fc::MouseUp_Event:
|
|
||||||
case fc::MouseDoubleClick_Event:
|
|
||||||
case fc::MouseWheel_Event:
|
|
||||||
case fc::MouseMove_Event:
|
|
||||||
case fc::FocusIn_Event:
|
|
||||||
case fc::FocusOut_Event:
|
|
||||||
case fc::ChildFocusIn_Event:
|
|
||||||
case fc::ChildFocusOut_Event:
|
|
||||||
case fc::Accelerator_Event:
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
// Sends the event event directly to receiver
|
||||||
break;
|
return receiver->event(event);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throw away mouse events for disabled widgets
|
|
||||||
if ( event->type() >= fc::MouseDown_Event
|
|
||||||
&& event->type() <= fc::MouseMove_Event
|
|
||||||
&& ! widget->isEnabled() )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends event event directly to receiver
|
|
||||||
auto r = const_cast<FObject*>(receiver);
|
|
||||||
return r->event(const_cast<FEvent*>(event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FApplication::queueEvent ( const FObject* receiver
|
void FApplication::queueEvent (FObject* receiver, FEvent* event)
|
||||||
, const FEvent* event )
|
|
||||||
{
|
{
|
||||||
if ( ! receiver )
|
if ( ! receiver )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// queue this event
|
// queue this event
|
||||||
eventPair send_event (receiver, std::make_shared<const FEvent>(*event));
|
eventPair send_event (receiver, std::make_shared<FEvent>(*event));
|
||||||
event_queue->push_back(send_event);
|
event_queue.push_back(send_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -248,9 +194,9 @@ void FApplication::sendQueuedEvents()
|
||||||
{
|
{
|
||||||
while ( eventInQueue() )
|
while ( eventInQueue() )
|
||||||
{
|
{
|
||||||
sendEvent( event_queue->front().first,
|
sendEvent( event_queue.front().first,
|
||||||
event_queue->front().second.get() );
|
event_queue.front().second.get() );
|
||||||
event_queue->pop_front();
|
event_queue.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +204,7 @@ void FApplication::sendQueuedEvents()
|
||||||
bool FApplication::eventInQueue()
|
bool FApplication::eventInQueue()
|
||||||
{
|
{
|
||||||
if ( app_object )
|
if ( app_object )
|
||||||
return ( ! event_queue->empty() );
|
return ( ! event_queue.empty() );
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -273,13 +219,13 @@ bool FApplication::removeQueuedEvent (const FObject* receiver)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool retval{false};
|
bool retval{false};
|
||||||
auto iter = event_queue->begin();
|
auto iter = event_queue.begin();
|
||||||
|
|
||||||
while ( iter != event_queue->end() )
|
while ( iter != event_queue.end() )
|
||||||
{
|
{
|
||||||
if ( iter->first == receiver )
|
if ( iter->first == receiver )
|
||||||
{
|
{
|
||||||
iter = event_queue->erase(iter);
|
iter = event_queue.erase(iter);
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -404,16 +350,6 @@ void FApplication::init (uInt64 key_time, uInt64 dblclick_time)
|
||||||
// Set the default double click interval
|
// Set the default double click interval
|
||||||
if ( mouse )
|
if ( mouse )
|
||||||
mouse->setDblclickInterval (dblclick_time);
|
mouse->setDblclickInterval (dblclick_time);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
event_queue = new eventQueue;
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc& ex)
|
|
||||||
{
|
|
||||||
std::cerr << bad_alloc_str << ex.what() << std::endl;
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -631,7 +567,7 @@ inline void FApplication::sendEscapeKeyPressEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FApplication::sendKeyDownEvent (const FWidget* widget)
|
inline bool FApplication::sendKeyDownEvent (FWidget* widget)
|
||||||
{
|
{
|
||||||
// Send key down event
|
// Send key down event
|
||||||
FKeyEvent k_down_ev (fc::KeyDown_Event, keyboard->getKey());
|
FKeyEvent k_down_ev (fc::KeyDown_Event, keyboard->getKey());
|
||||||
|
@ -640,7 +576,7 @@ inline bool FApplication::sendKeyDownEvent (const FWidget* widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FApplication::sendKeyPressEvent (const FWidget* widget)
|
inline bool FApplication::sendKeyPressEvent (FWidget* widget)
|
||||||
{
|
{
|
||||||
// Send key press event
|
// Send key press event
|
||||||
FKeyEvent k_press_ev (fc::KeyPress_Event, keyboard->getKey());
|
FKeyEvent k_press_ev (fc::KeyPress_Event, keyboard->getKey());
|
||||||
|
@ -649,7 +585,7 @@ inline bool FApplication::sendKeyPressEvent (const FWidget* widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FApplication::sendKeyUpEvent (const FWidget* widget)
|
inline bool FApplication::sendKeyUpEvent (FWidget* widget)
|
||||||
{
|
{
|
||||||
// Send key up event
|
// Send key up event
|
||||||
FKeyEvent k_up_ev (fc::KeyUp_Event, keyboard->getKey());
|
FKeyEvent k_up_ev (fc::KeyUp_Event, keyboard->getKey());
|
||||||
|
@ -1180,10 +1116,63 @@ bool FApplication::processNextEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FApplication::performTimerAction ( const FObject* receiver
|
void FApplication::performTimerAction (FObject* receiver, FEvent* event)
|
||||||
, const FEvent* event )
|
|
||||||
{
|
{
|
||||||
sendEvent (receiver, event);
|
sendEvent (receiver, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
bool FApplication::isEventProcessable (FObject* receiver, FEvent* event )
|
||||||
|
{
|
||||||
|
if ( ! receiver->isWidget() ) // No restrictions for non-widgets
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const auto widget = static_cast<const FWidget*>(receiver);
|
||||||
|
|
||||||
|
if ( getModalDialogCounter() > 0 )
|
||||||
|
{
|
||||||
|
const FWidget* window;
|
||||||
|
|
||||||
|
if ( widget->isWindowWidget() )
|
||||||
|
window = widget;
|
||||||
|
else
|
||||||
|
window = FWindow::getWindowWidget(widget);
|
||||||
|
|
||||||
|
// block events for widgets in non modal windows
|
||||||
|
if ( window
|
||||||
|
&& ! window->getFlags().modal
|
||||||
|
&& ! window->isMenuWidget() )
|
||||||
|
{
|
||||||
|
switch ( uInt(event->type()) )
|
||||||
|
{
|
||||||
|
case fc::KeyPress_Event:
|
||||||
|
case fc::KeyUp_Event:
|
||||||
|
case fc::KeyDown_Event:
|
||||||
|
case fc::MouseDown_Event:
|
||||||
|
case fc::MouseUp_Event:
|
||||||
|
case fc::MouseDoubleClick_Event:
|
||||||
|
case fc::MouseWheel_Event:
|
||||||
|
case fc::MouseMove_Event:
|
||||||
|
case fc::FocusIn_Event:
|
||||||
|
case fc::FocusOut_Event:
|
||||||
|
case fc::ChildFocusIn_Event:
|
||||||
|
case fc::ChildFocusOut_Event:
|
||||||
|
case fc::Accelerator_Event:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw away mouse events for disabled widgets
|
||||||
|
if ( event->type() >= fc::MouseDown_Event
|
||||||
|
&& event->type() <= fc::MouseMove_Event
|
||||||
|
&& ! widget->isEnabled() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace finalcut
|
} // namespace finalcut
|
||||||
|
|
|
@ -427,7 +427,7 @@ uInt FObject::processTimerEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FObject::performTimerAction (const FObject*, const FEvent*)
|
void FObject::performTimerAction (FObject*, FEvent*)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
} // namespace finalcut
|
} // namespace finalcut
|
||||||
|
|
|
@ -105,7 +105,8 @@ FWidget::~FWidget() // destructor
|
||||||
{
|
{
|
||||||
processDestroy();
|
processDestroy();
|
||||||
delCallbacks();
|
delCallbacks();
|
||||||
FApplication::removeQueuedEvent(this);
|
auto app_object = FApplication::getApplicationObject();
|
||||||
|
app_object->removeQueuedEvent(this);
|
||||||
|
|
||||||
// unset clicked widget
|
// unset clicked widget
|
||||||
if ( this == getClickedWidget() )
|
if ( this == getClickedWidget() )
|
||||||
|
@ -1888,7 +1889,7 @@ FWidget::FCallbackPtr FWidget::getCallbackPtr (FCallback cb_function)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
bool FWidget::changeFocus ( FWidget* follower, const FWidget* parent
|
bool FWidget::changeFocus ( FWidget* follower, FWidget* parent
|
||||||
, fc::FocusTypes ft )
|
, fc::FocusTypes ft )
|
||||||
{
|
{
|
||||||
FFocusEvent out (fc::FocusOut_Event);
|
FFocusEvent out (fc::FocusOut_Event);
|
||||||
|
|
|
@ -116,11 +116,11 @@ class FApplication : public FWidget
|
||||||
void exitLoop();
|
void exitLoop();
|
||||||
static void exit (int = 0);
|
static void exit (int = 0);
|
||||||
void quit();
|
void quit();
|
||||||
static bool sendEvent (const FObject*, const FEvent*);
|
static bool sendEvent (FObject*, FEvent*);
|
||||||
static void queueEvent (const FObject*, const FEvent*);
|
void queueEvent (FObject*, FEvent*);
|
||||||
static void sendQueuedEvents ();
|
void sendQueuedEvents ();
|
||||||
static bool eventInQueue();
|
bool eventInQueue();
|
||||||
static bool removeQueuedEvent (const FObject*);
|
bool removeQueuedEvent (const FObject*);
|
||||||
static FWidget* processParameters (const int&, char*[]);
|
static FWidget* processParameters (const int&, char*[]);
|
||||||
static void showParameterUsage ()
|
static void showParameterUsage ()
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
@ -134,8 +134,8 @@ class FApplication : public FWidget
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Typedefs
|
// Typedefs
|
||||||
typedef std::pair<const FObject*, std::shared_ptr<const FEvent> > eventPair;
|
typedef std::pair<FObject*, std::shared_ptr<FEvent> > eventPair;
|
||||||
typedef std::deque<eventPair> eventQueue;
|
typedef std::deque<eventPair> FEventQueue;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
void init (uInt64, uInt64);
|
void init (uInt64, uInt64);
|
||||||
|
@ -148,9 +148,9 @@ class FApplication : public FWidget
|
||||||
void escapeKeyPressed();
|
void escapeKeyPressed();
|
||||||
void performKeyboardAction();
|
void performKeyboardAction();
|
||||||
void sendEscapeKeyPressEvent();
|
void sendEscapeKeyPressEvent();
|
||||||
bool sendKeyDownEvent (const FWidget*);
|
bool sendKeyDownEvent (FWidget*);
|
||||||
bool sendKeyPressEvent (const FWidget*);
|
bool sendKeyPressEvent (FWidget*);
|
||||||
bool sendKeyUpEvent (const FWidget*);
|
bool sendKeyUpEvent (FWidget*);
|
||||||
void sendKeyboardAccelerator();
|
void sendKeyboardAccelerator();
|
||||||
void processKeyboardEvent();
|
void processKeyboardEvent();
|
||||||
bool processDialogSwitchAccelerator();
|
bool processDialogSwitchAccelerator();
|
||||||
|
@ -178,20 +178,20 @@ class FApplication : public FWidget
|
||||||
void processResizeEvent();
|
void processResizeEvent();
|
||||||
void processCloseWidget();
|
void processCloseWidget();
|
||||||
bool processNextEvent();
|
bool processNextEvent();
|
||||||
void performTimerAction ( const FObject*
|
void performTimerAction (FObject*, FEvent*) override;
|
||||||
, const FEvent* ) override;
|
static bool isEventProcessable (FObject*, FEvent*);
|
||||||
|
|
||||||
// Data members
|
// Data members
|
||||||
int app_argc;
|
int app_argc{};
|
||||||
char** app_argv;
|
char** app_argv{};
|
||||||
uInt64 key_timeout{100000}; // 100 ms
|
uInt64 key_timeout{100000}; // 100 ms
|
||||||
uInt64 dblclick_interval{500000}; // 500 ms
|
uInt64 dblclick_interval{500000}; // 500 ms
|
||||||
static FMouseControl* mouse;
|
FEventQueue event_queue{};
|
||||||
static eventQueue* event_queue;
|
|
||||||
static int quit_code;
|
static int quit_code;
|
||||||
static bool quit_now;
|
static bool quit_now;
|
||||||
static int loop_level;
|
static int loop_level;
|
||||||
static bool process_timer_event;
|
static bool process_timer_event;
|
||||||
|
static FMouseControl* mouse;
|
||||||
static FKeyboard* keyboard;
|
static FKeyboard* keyboard;
|
||||||
static FWidget* keyboard_widget;
|
static FWidget* keyboard_widget;
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,7 +50,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define to 1 if GPM mouse is enabled */
|
/* Define to 1 if GPM mouse is enabled */
|
||||||
/* #undef HAVE_LIBGPM */
|
#ifndef F_HAVE_LIBGPM
|
||||||
|
#define F_HAVE_LIBGPM 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define to 1 if you have the <linux/fb.h> header file. */
|
/* Define to 1 if you have the <linux/fb.h> header file. */
|
||||||
#ifndef F_HAVE_LINUX_FB_H
|
#ifndef F_HAVE_LINUX_FB_H
|
||||||
|
|
|
@ -153,8 +153,7 @@ class FObject
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Method
|
// Method
|
||||||
virtual void performTimerAction ( const FObject*
|
virtual void performTimerAction (FObject*, FEvent*);
|
||||||
, const FEvent* );
|
|
||||||
|
|
||||||
// Data members
|
// Data members
|
||||||
FObject* parent_obj{nullptr};
|
FObject* parent_obj{nullptr};
|
||||||
|
|
|
@ -405,7 +405,7 @@ class FWidget : public FVTerm, public FObject
|
||||||
void emitWheelCallback (const FWheelEvent*);
|
void emitWheelCallback (const FWheelEvent*);
|
||||||
void setWindowFocus (bool);
|
void setWindowFocus (bool);
|
||||||
FCallbackPtr getCallbackPtr (FCallback);
|
FCallbackPtr getCallbackPtr (FCallback);
|
||||||
bool changeFocus (FWidget*, const FWidget*, fc::FocusTypes);
|
bool changeFocus (FWidget*, FWidget*, fc::FocusTypes);
|
||||||
void processDestroy();
|
void processDestroy();
|
||||||
virtual void draw();
|
virtual void draw();
|
||||||
void drawWindows();
|
void drawWindows();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the Final Cut widget toolkit *
|
* This file is part of the Final Cut widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2018-2019 Markus Gans *
|
* Copyright 2018-2020 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* The Final Cut is free software; you can redistribute it and/or *
|
* The Final Cut is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU Lesser General Public License *
|
* modify it under the terms of the GNU Lesser General Public License *
|
||||||
|
@ -69,7 +69,7 @@ class FObject_protected : public finalcut::FObject
|
||||||
return finalcut::FObject::isWidget();
|
return finalcut::FObject::isWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performTimerAction (const FObject*, const finalcut::FEvent*)
|
virtual void performTimerAction (FObject*, finalcut::FEvent*)
|
||||||
{
|
{
|
||||||
std::cout << ".";
|
std::cout << ".";
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
Loading…
Reference in New Issue