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>
|
||||
* Better support of general arrow keys
|
||||
* Improved event handling code
|
||||
|
||||
2020-04-13 Markus Gans <guru.mail@muenster.de>
|
||||
* Several small code improvements
|
||||
|
|
|
@ -130,7 +130,7 @@ int main (int argc, char* argv[])
|
|||
|
||||
// Scroll to the focused child element
|
||||
finalcut::FFocusEvent cfi (finalcut::fc::ChildFocusIn_Event);
|
||||
finalcut::FApplication::queueEvent(&checkButtonGroup, &cfi);
|
||||
app.queueEvent(&checkButtonGroup, &cfi);
|
||||
|
||||
// Create a OK button
|
||||
finalcut::FButton ok("&OK", &dgl);
|
||||
|
|
|
@ -59,8 +59,6 @@ int FApplication::loop_level {0}; // event loop level
|
|||
int FApplication::quit_code {0};
|
||||
bool FApplication::quit_now {false};
|
||||
|
||||
FApplication::eventQueue* FApplication::event_queue{nullptr};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FApplication
|
||||
|
@ -100,10 +98,6 @@ FApplication::FApplication ( const int& _argc
|
|||
//----------------------------------------------------------------------
|
||||
FApplication::~FApplication() // destructor
|
||||
{
|
||||
if ( event_queue )
|
||||
delete event_queue;
|
||||
|
||||
event_queue = nullptr;
|
||||
app_object = nullptr;
|
||||
}
|
||||
|
||||
|
@ -172,75 +166,27 @@ void FApplication::quit()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool FApplication::sendEvent ( const FObject* receiver
|
||||
, const FEvent* event )
|
||||
bool FApplication::sendEvent (FObject* receiver, FEvent* event )
|
||||
{
|
||||
if ( quit_now || app_exit_loop || ! receiver )
|
||||
return false;
|
||||
|
||||
if ( receiver->isWidget() )
|
||||
{
|
||||
const auto widget = static_cast<const FWidget*>(receiver);
|
||||
if ( ! isEventProcessable (receiver, event) )
|
||||
return false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Sends event event directly to receiver
|
||||
auto r = const_cast<FObject*>(receiver);
|
||||
return r->event(const_cast<FEvent*>(event));
|
||||
// Sends the event event directly to receiver
|
||||
return receiver->event(event);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FApplication::queueEvent ( const FObject* receiver
|
||||
, const FEvent* event )
|
||||
void FApplication::queueEvent (FObject* receiver, FEvent* event)
|
||||
{
|
||||
if ( ! receiver )
|
||||
return;
|
||||
|
||||
// queue this event
|
||||
eventPair send_event (receiver, std::make_shared<const FEvent>(*event));
|
||||
event_queue->push_back(send_event);
|
||||
eventPair send_event (receiver, std::make_shared<FEvent>(*event));
|
||||
event_queue.push_back(send_event);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -248,9 +194,9 @@ void FApplication::sendQueuedEvents()
|
|||
{
|
||||
while ( eventInQueue() )
|
||||
{
|
||||
sendEvent( event_queue->front().first,
|
||||
event_queue->front().second.get() );
|
||||
event_queue->pop_front();
|
||||
sendEvent( event_queue.front().first,
|
||||
event_queue.front().second.get() );
|
||||
event_queue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,7 +204,7 @@ void FApplication::sendQueuedEvents()
|
|||
bool FApplication::eventInQueue()
|
||||
{
|
||||
if ( app_object )
|
||||
return ( ! event_queue->empty() );
|
||||
return ( ! event_queue.empty() );
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -273,13 +219,13 @@ bool FApplication::removeQueuedEvent (const FObject* receiver)
|
|||
return 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 )
|
||||
{
|
||||
iter = event_queue->erase(iter);
|
||||
iter = event_queue.erase(iter);
|
||||
retval = true;
|
||||
}
|
||||
else
|
||||
|
@ -404,16 +350,6 @@ void FApplication::init (uInt64 key_time, uInt64 dblclick_time)
|
|||
// Set the default double click interval
|
||||
if ( mouse )
|
||||
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
|
||||
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
|
||||
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
|
||||
FKeyEvent k_up_ev (fc::KeyUp_Event, keyboard->getKey());
|
||||
|
@ -1180,10 +1116,63 @@ bool FApplication::processNextEvent()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FApplication::performTimerAction ( const FObject* receiver
|
||||
, const FEvent* event )
|
||||
void FApplication::performTimerAction (FObject* receiver, FEvent* 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
|
||||
|
|
|
@ -427,7 +427,7 @@ uInt FObject::processTimerEvent()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FObject::performTimerAction (const FObject*, const FEvent*)
|
||||
void FObject::performTimerAction (FObject*, FEvent*)
|
||||
{ }
|
||||
|
||||
} // namespace finalcut
|
||||
|
|
|
@ -105,7 +105,8 @@ FWidget::~FWidget() // destructor
|
|||
{
|
||||
processDestroy();
|
||||
delCallbacks();
|
||||
FApplication::removeQueuedEvent(this);
|
||||
auto app_object = FApplication::getApplicationObject();
|
||||
app_object->removeQueuedEvent(this);
|
||||
|
||||
// unset clicked widget
|
||||
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 )
|
||||
{
|
||||
FFocusEvent out (fc::FocusOut_Event);
|
||||
|
|
|
@ -116,17 +116,17 @@ class FApplication : public FWidget
|
|||
void exitLoop();
|
||||
static void exit (int = 0);
|
||||
void quit();
|
||||
static bool sendEvent (const FObject*, const FEvent*);
|
||||
static void queueEvent (const FObject*, const FEvent*);
|
||||
static void sendQueuedEvents ();
|
||||
static bool eventInQueue();
|
||||
static bool removeQueuedEvent (const FObject*);
|
||||
static bool sendEvent (FObject*, FEvent*);
|
||||
void queueEvent (FObject*, FEvent*);
|
||||
void sendQueuedEvents ();
|
||||
bool eventInQueue();
|
||||
bool removeQueuedEvent (const FObject*);
|
||||
static FWidget* processParameters (const int&, char*[]);
|
||||
static void showParameterUsage ()
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
__attribute__((noreturn))
|
||||
#endif
|
||||
;
|
||||
;
|
||||
static void closeConfirmationDialog (FWidget*, FCloseEvent*);
|
||||
|
||||
// Callback method
|
||||
|
@ -134,8 +134,8 @@ class FApplication : public FWidget
|
|||
|
||||
private:
|
||||
// Typedefs
|
||||
typedef std::pair<const FObject*, std::shared_ptr<const FEvent> > eventPair;
|
||||
typedef std::deque<eventPair> eventQueue;
|
||||
typedef std::pair<FObject*, std::shared_ptr<FEvent> > eventPair;
|
||||
typedef std::deque<eventPair> FEventQueue;
|
||||
|
||||
// Methods
|
||||
void init (uInt64, uInt64);
|
||||
|
@ -148,9 +148,9 @@ class FApplication : public FWidget
|
|||
void escapeKeyPressed();
|
||||
void performKeyboardAction();
|
||||
void sendEscapeKeyPressEvent();
|
||||
bool sendKeyDownEvent (const FWidget*);
|
||||
bool sendKeyPressEvent (const FWidget*);
|
||||
bool sendKeyUpEvent (const FWidget*);
|
||||
bool sendKeyDownEvent (FWidget*);
|
||||
bool sendKeyPressEvent (FWidget*);
|
||||
bool sendKeyUpEvent (FWidget*);
|
||||
void sendKeyboardAccelerator();
|
||||
void processKeyboardEvent();
|
||||
bool processDialogSwitchAccelerator();
|
||||
|
@ -178,20 +178,20 @@ class FApplication : public FWidget
|
|||
void processResizeEvent();
|
||||
void processCloseWidget();
|
||||
bool processNextEvent();
|
||||
void performTimerAction ( const FObject*
|
||||
, const FEvent* ) override;
|
||||
void performTimerAction (FObject*, FEvent*) override;
|
||||
static bool isEventProcessable (FObject*, FEvent*);
|
||||
|
||||
// Data members
|
||||
int app_argc;
|
||||
char** app_argv;
|
||||
int app_argc{};
|
||||
char** app_argv{};
|
||||
uInt64 key_timeout{100000}; // 100 ms
|
||||
uInt64 dblclick_interval{500000}; // 500 ms
|
||||
static FMouseControl* mouse;
|
||||
static eventQueue* event_queue;
|
||||
FEventQueue event_queue{};
|
||||
static int quit_code;
|
||||
static bool quit_now;
|
||||
static int loop_level;
|
||||
static bool process_timer_event;
|
||||
static FMouseControl* mouse;
|
||||
static FKeyboard* keyboard;
|
||||
static FWidget* keyboard_widget;
|
||||
};
|
||||
|
|
|
@ -50,7 +50,9 @@
|
|||
#endif
|
||||
|
||||
/* 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. */
|
||||
#ifndef F_HAVE_LINUX_FB_H
|
||||
|
|
|
@ -153,8 +153,7 @@ class FObject
|
|||
|
||||
private:
|
||||
// Method
|
||||
virtual void performTimerAction ( const FObject*
|
||||
, const FEvent* );
|
||||
virtual void performTimerAction (FObject*, FEvent*);
|
||||
|
||||
// Data members
|
||||
FObject* parent_obj{nullptr};
|
||||
|
|
|
@ -405,7 +405,7 @@ class FWidget : public FVTerm, public FObject
|
|||
void emitWheelCallback (const FWheelEvent*);
|
||||
void setWindowFocus (bool);
|
||||
FCallbackPtr getCallbackPtr (FCallback);
|
||||
bool changeFocus (FWidget*, const FWidget*, fc::FocusTypes);
|
||||
bool changeFocus (FWidget*, FWidget*, fc::FocusTypes);
|
||||
void processDestroy();
|
||||
virtual void draw();
|
||||
void drawWindows();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* *
|
||||
* 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 *
|
||||
* 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();
|
||||
}
|
||||
|
||||
virtual void performTimerAction (const FObject*, const finalcut::FEvent*)
|
||||
virtual void performTimerAction (FObject*, finalcut::FEvent*)
|
||||
{
|
||||
std::cout << ".";
|
||||
fflush(stdout);
|
||||
|
|
Loading…
Reference in New Issue