Refactoring FApplication::processKeyboardEvent

This commit is contained in:
Markus Gans 2018-01-28 19:54:52 +01:00
parent 213407e3a5
commit 7eb6bfa587
6 changed files with 245 additions and 233 deletions

View File

@ -1,3 +1,8 @@
2017-01-28 Markus Gans <guru.mail@muenster.de>
* Refactoring FApplication::processKeyboardEvent
* Shorter methods and a fix for recreating new windows
in the window example
2017-01-25 Markus Gans <guru.mail@muenster.de>
* UTF-8 fix for Solaris

View File

@ -101,9 +101,9 @@ fi
if $MAKE
then
echo "${GREEN}Successful compiled${NORMAL}"
printf '%bSuccessful compiled%b\n' "${GREEN}" "${NORMAL}"
else
echo "${RED}Error on compile!${NORMAL}" 1>&2
printf '%bError on compile!%b\n' "${RED}" "${NORMAL}" 1>&2
exit 1
fi

View File

@ -3,7 +3,7 @@
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2016-2017 Markus Gans *
* Copyright 2016-2018 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 *
@ -117,9 +117,6 @@ SmallWindow::~SmallWindow()
{
// Remove own timer
delOwnTimer();
// Remove all callbacks before Window::cb_destroyWindow() will be called
delCallbacks();
}
//----------------------------------------------------------------------
@ -183,7 +180,9 @@ class Window : public FDialog
~Window();
private:
// Typedef
// Typedefs
typedef void (Window::*WindowCallback)(FWidget*, data_ptr);
typedef void (FApplication::*FAppCallback)(FWidget*, data_ptr);
typedef struct
{
bool is_open;
@ -199,8 +198,12 @@ class Window : public FDialog
Window& operator = (const Window&);
// Method
void createFileMenuItems (FMenu*);
void createDialogButtons();
void activateWindow (FDialog*);
void adjustSize();
void addClickedCallback (FWidget*, WindowCallback);
void addClickedCallback (FWidget*, FAppCallback);
// Event handlers
void onClose (FCloseEvent*);
@ -222,20 +225,68 @@ Window::Window (FWidget* parent)
: FDialog(parent)
, windows()
{
FMenu* File;
FDialogListMenu* DglList;
FString drop_down_symbol;
// menu bar
FMenuBar* Menubar = new FMenuBar (this);
FMenuBar* Menubar;
FStatusBar* statusbar;
// menu bar item
FMenu* File = new FMenu ("&File", Menubar);
// Menu bar
Menubar = new FMenuBar (this);
// Menu bar item
File = new FMenu ("&File", Menubar);
File->setStatusbarMessage ("File management commands");
// dialog list menu item
// Dialog list menu item
drop_down_symbol = wchar_t(fc::BlackDownPointingTriangle);
FDialogListMenu* DglList = new FDialogListMenu (drop_down_symbol, Menubar);
DglList = new FDialogListMenu (drop_down_symbol, Menubar);
DglList->setStatusbarMessage ("List of all the active dialogs");
// File menu items
createFileMenuItems (File);
// Dialog buttons
createDialogButtons();
// Statusbar at the bottom
statusbar = new FStatusBar (this);
statusbar->setMessage("Status bar message");
// Generate data vector for the windows
for (int n = 1; n <= 6; n++)
{
win_data* win_dat = new win_data;
win_dat->is_open = false;
win_dat->title = new FString();
win_dat->title->sprintf("Window %d", n);
windows.push_back(win_dat);
}
}
//----------------------------------------------------------------------
Window::~Window()
{
std::vector<win_data*>::iterator iter;
iter = windows.begin();
while ( iter != windows.end() )
{
win_data* win_dat = *iter;
// Remove all callbacks before Window::cb_destroyWindow() will be called
if ( win_dat->is_open && win_dat->dgl )
win_dat->dgl->delCallbacks();
delete win_dat->title;
delete win_dat;
iter = windows.erase(iter);
}
}
//----------------------------------------------------------------------
void Window::createFileMenuItems (FMenu* File)
{
// "File" menu item
FMenuItem* New = new FMenuItem ("&New", File);
New->setStatusbarMessage ("Create the windows");
@ -261,11 +312,18 @@ Window::Window (FWidget* parent)
Quit->addAccelerator (fc::Fmkey_x); // Meta/Alt + X
Quit->setStatusbarMessage ("Exit the program");
// Statusbar at the bottom
FStatusBar* statusbar = new FStatusBar (this);
statusbar->setMessage("Status bar message");
// Add menu item callback
addClickedCallback (New, &Window::cb_createWindows);
addClickedCallback (Close, &Window::cb_closeWindows);
addClickedCallback (Next, &Window::cb_next);
addClickedCallback (Previous, &Window::cb_previous);
addClickedCallback (Quit, &FApplication::cb_exitApp);
}
// Buttons
//----------------------------------------------------------------------
void Window::createDialogButtons()
{
// Dialog buttons
FButton* CreateButton = new FButton (this);
CreateButton->setGeometry(2, 2, 9, 1);
CreateButton->setText (L"&Create");
@ -278,78 +336,10 @@ Window::Window (FWidget* parent)
QuitButton->setGeometry(28, 2, 9, 1);
QuitButton->setText (L"&Quit");
// Add menu item callback
New->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Window::cb_createWindows)
);
Close->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Window::cb_closeWindows)
);
Next->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Window::cb_next)
);
Previous->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Window::cb_previous)
);
Quit->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FApplication::cb_exitApp)
);
// Add button callback
CreateButton->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Window::cb_createWindows)
);
CloseButton->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Window::cb_closeWindows)
);
QuitButton->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FApplication::cb_exitApp)
);
for (int n = 1; n <= 6; n++)
{
win_data* win_dat = new win_data;
win_dat->is_open = false;
win_dat->title = new FString();
win_dat->title->sprintf("Window %d", n);
windows.push_back(win_dat);
}
}
//----------------------------------------------------------------------
Window::~Window()
{
std::vector<win_data*>::iterator iter;
iter = windows.begin();
while ( iter != windows.end() )
{
delete (*iter)->title;
delete *iter;
iter = windows.erase(iter);
}
addClickedCallback (CreateButton, &Window::cb_createWindows);
addClickedCallback (CloseButton, &Window::cb_closeWindows);
addClickedCallback (QuitButton, &FApplication::cb_exitApp);
}
//----------------------------------------------------------------------
@ -400,6 +390,32 @@ void Window::adjustSize()
FDialog::adjustSize();
}
//----------------------------------------------------------------------
void Window::addClickedCallback (FWidget* widget, WindowCallback call)
{
FMemberCallback callback
= reinterpret_cast<FWidget::FMemberCallback>(call);
widget->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, callback)
);
}
//----------------------------------------------------------------------
void Window::addClickedCallback (FWidget* widget, FAppCallback call)
{
FMemberCallback callback
= reinterpret_cast<FWidget::FMemberCallback>(call);
widget->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, callback)
);
}
//----------------------------------------------------------------------
void Window::onClose (FCloseEvent* ev)
{
@ -551,7 +567,10 @@ void Window::cb_destroyWindow (FWidget*, data_ptr data)
win_data* win_dat = static_cast<win_data*>(data);
if ( win_dat )
{
win_dat->is_open = false;
win_dat->dgl = 0;
}
}

View File

@ -136,13 +136,15 @@ class FApplication : public FWidget
FApplication& operator = (const FApplication&);
// Methods
void init();
void init (long, long);
static void cmd_options (const int&, char*[]);
bool KeyPressed();
ssize_t readKey();
FWidget* findKeyboardWidget();
bool getKeyPressedState();
void keyboardBufferTimeout (FWidget*);
void parseKeyPuffer (FWidget*);
void performKeyboardAction (FWidget*);
void sendEscapeKeyPressEvent (FWidget*);
bool sendKeyDownEvent (FWidget*);
bool sendKeyPressEvent (FWidget*);
@ -200,6 +202,7 @@ class FApplication : public FWidget
long key_timeout;
long dblclick_interval;
struct timeval time_keypressed;
static FMouseControl* mouse;
static eventQueue* event_queue;
static int quit_code;
static bool quit_now;

View File

@ -252,6 +252,7 @@ inline bool FMouseGPM::isGpmMouseEnabled()
{ return gpm_mouse_enabled; }
#endif
//----------------------------------------------------------------------
// class FMouseX11
//----------------------------------------------------------------------

View File

@ -35,17 +35,19 @@ static FApplication* rootObj = 0;
static bool app_exit_loop = false;
// static attributes
int FApplication::loop_level = 0; // event loop level
FWidget* FApplication::main_widget = 0; // main application widget
FWidget* FApplication::active_window = 0; // the active window
FWidget* FApplication::focus_widget = 0; // has keyboard input focus
FWidget* FApplication::clicked_widget = 0; // is focused by click
FWidget* FApplication::open_menu = 0; // currently open menu
FWidget* FApplication::move_size_widget = 0; // move/size by keyboard
int FApplication::quit_code = 0;
bool FApplication::quit_now = false;
int FApplication::loop_level = 0; // event loop level
FWidget* FApplication::main_widget = 0; // main application widget
FWidget* FApplication::active_window = 0; // the active window
FWidget* FApplication::focus_widget = 0; // has keyboard input focus
FWidget* FApplication::clicked_widget = 0; // is focused by click
FWidget* FApplication::open_menu = 0; // currently open menu
FWidget* FApplication::move_size_widget = 0; // move/size by keyboard
FMouseControl* FApplication::mouse = 0; // mouse control
int FApplication::quit_code = 0;
bool FApplication::quit_now = false;
FApplication::eventQueue* FApplication::event_queue = 0;
FApplication::eventQueue* FApplication::event_queue = 0;
//----------------------------------------------------------------------
// class FApplication
@ -71,15 +73,6 @@ FApplication::FApplication ( const int& _argc
&& "FApplication: There should be only one application object" );
rootObj = this;
// Set the keyboard keypress timeout
setKeypressTimeout (key_timeout);
// Set the default double click interval
FMouseControl* mouse = getMouseControl();
if ( mouse )
mouse->setDblclickInterval (dblclick_interval);
if ( ! (_argc && _argv) )
{
static char* empty = C_STR("");
@ -87,7 +80,7 @@ FApplication::FApplication ( const int& _argc
app_argv = static_cast<char**>(&empty);
}
init();
init (key_timeout, dblclick_interval);
}
//----------------------------------------------------------------------
@ -362,16 +355,25 @@ void FApplication::closeConfirmationDialog (FWidget* w, FCloseEvent* ev)
// private methods of FApplication
//----------------------------------------------------------------------
void FApplication::init()
void FApplication::init (long key_timeout, long dblclick_interval)
{
// init keyboard values
// Initialize keyboard values
time_keypressed.tv_sec = 0;
time_keypressed.tv_usec = 0;
FMouseControl* mouse = getMouseControl();
// Set the keyboard keypress timeout
setKeypressTimeout (key_timeout);
// Initialize mouse control
mouse = getMouseControl();
// Set stdin number for a gpm-mouse
if ( mouse )
mouse->setStdinNo(stdin_no);
mouse->setStdinNo (stdin_no);
// Set the default double click interval
if ( mouse )
mouse->setDblclickInterval (dblclick_interval);
try
{
@ -383,7 +385,7 @@ void FApplication::init()
std::abort();
}
// init arrays with '\0'
// Initialize arrays with '\0'
std::fill_n (k_buf, sizeof(k_buf), '\0');
std::fill_n (fifo_buf, fifo_buf_size, '\0');
}
@ -391,7 +393,7 @@ void FApplication::init()
//----------------------------------------------------------------------
void FApplication::cmd_options (const int& argc, char* argv[])
{
// interpret the command line options
// Interpret the command line options
while ( true )
{
@ -509,6 +511,15 @@ inline FWidget* FApplication::findKeyboardWidget()
return widget;
}
//----------------------------------------------------------------------
inline bool FApplication::getKeyPressedState()
{
if ( mouse && mouse->isGpmMouseEnabled() )
return mouse->getGpmKeyPressed(unprocessedInput());
return KeyPressed();
}
//----------------------------------------------------------------------
inline void FApplication::keyboardBufferTimeout (FWidget*)
{
@ -523,14 +534,97 @@ inline void FApplication::keyboardBufferTimeout (FWidget*)
}
//----------------------------------------------------------------------
inline bool FApplication::getKeyPressedState()
inline void FApplication::parseKeyPuffer (FWidget* widget)
{
FMouseControl* mouse = getMouseControl();
register ssize_t bytesread;
getCurrentTime (&time_keypressed);
if ( mouse && mouse->isGpmMouseEnabled() )
return mouse->getGpmKeyPressed(unprocessedInput());
if ( quit_now || app_exit_loop )
return;
return KeyPressed();
while ( (bytesread = readKey()) > 0 )
{
if ( bytesread + fifo_offset <= fifo_buf_size )
{
for (int i = 0; i < bytesread; i++)
{
fifo_buf[fifo_offset] = k_buf[i];
fifo_offset++;
}
fifo_in_use = true;
}
// Read the rest from the fifo buffer
while ( ! widget->isKeypressTimeout(&time_keypressed)
&& fifo_offset > 0
&& key != NEED_MORE_DATA )
{
key = FTerm::parseKeyString(fifo_buf, fifo_buf_size, &time_keypressed);
if ( key != NEED_MORE_DATA )
performKeyboardAction (widget);
fifo_offset = int(std::strlen(fifo_buf));
}
// Send key up event
sendKeyUpEvent (widget);
key = 0;
}
std::fill_n (k_buf, sizeof(k_buf), '\0');
}
//----------------------------------------------------------------------
inline void FApplication::performKeyboardAction (FWidget* widget)
{
#if defined(__linux__)
key = linuxModifierKeyCorrection (key);
#endif
switch ( key )
{
case fc::Fckey_l: // Ctrl-L (redraw the screen)
redraw();
break;
case fc::Fkey_mouse:
if ( mouse )
{
mouse->setRawData (FMouse::x11, fifo_buf, sizeof(fifo_buf));
unprocessedInput() = mouse->isInputDataPending();
processMouseEvent();
}
break;
case fc::Fkey_extended_mouse:
if ( mouse )
{
mouse->setRawData (FMouse::sgr, fifo_buf, sizeof(fifo_buf));
unprocessedInput() = mouse->isInputDataPending();
processMouseEvent();
}
break;
case fc::Fkey_urxvt_mouse:
if ( mouse )
{
mouse->setRawData (FMouse::urxvt, fifo_buf, sizeof(fifo_buf));
unprocessedInput() = mouse->isInputDataPending();
processMouseEvent();
}
break;
default:
bool acceptKeyDown = sendKeyDownEvent (widget);
bool acceptKeyPress = sendKeyPressEvent (widget);
if ( ! (acceptKeyDown || acceptKeyPress) )
sendKeyboardAccelerator();
break;
}
}
//----------------------------------------------------------------------
@ -609,102 +703,13 @@ inline void FApplication::sendKeyboardAccelerator()
//----------------------------------------------------------------------
void FApplication::processKeyboardEvent()
{
bool isKeyPressed;
FWidget* widget = findKeyboardWidget();
FMouseControl* mouse = getMouseControl();
keyboardBufferTimeout(widget);
flush_out();
isKeyPressed = getKeyPressedState();
bool isKeyPressed = getKeyPressedState();
if ( isKeyPressed )
{
register ssize_t bytesread;
widget->getCurrentTime (&time_keypressed);
if ( quit_now || app_exit_loop )
return;
while ( (bytesread = readKey()) > 0 )
{
if ( bytesread + fifo_offset <= fifo_buf_size )
{
for (int i = 0; i < bytesread; i++)
{
fifo_buf[fifo_offset] = k_buf[i];
fifo_offset++;
}
fifo_in_use = true;
}
// read the rest from the fifo buffer
while ( ! widget->isKeypressTimeout(&time_keypressed)
&& fifo_offset > 0
&& key != NEED_MORE_DATA )
{
key = FTerm::parseKeyString(fifo_buf, fifo_buf_size, &time_keypressed);
if ( key != NEED_MORE_DATA )
{
#if defined(__linux__)
key = linuxModifierKeyCorrection (key);
#endif
switch ( key )
{
case fc::Fckey_l: // Ctrl-L (redraw the screen)
redraw();
break;
case fc::Fkey_mouse:
if ( mouse )
{
mouse->setRawData (FMouse::x11, fifo_buf, sizeof(fifo_buf));
unprocessedInput() = mouse->isInputDataPending();
processMouseEvent();
}
break;
case fc::Fkey_extended_mouse:
if ( mouse )
{
mouse->setRawData (FMouse::sgr, fifo_buf, sizeof(fifo_buf));
unprocessedInput() = mouse->isInputDataPending();
processMouseEvent();
}
break;
case fc::Fkey_urxvt_mouse:
if ( mouse )
{
mouse->setRawData (FMouse::urxvt, fifo_buf, sizeof(fifo_buf));
unprocessedInput() = mouse->isInputDataPending();
processMouseEvent();
}
break;
default:
bool acceptKeyDown = sendKeyDownEvent (widget);
bool acceptKeyPress = sendKeyPressEvent (widget);
if ( ! (acceptKeyDown || acceptKeyPress) )
sendKeyboardAccelerator();
break;
} // end of switch
}
fifo_offset = int(std::strlen(fifo_buf));
}
// Send key up event
sendKeyUpEvent (widget);
key = 0;
}
std::fill_n (k_buf, sizeof(k_buf), '\0');
}
parseKeyPuffer (widget);
// special case: Esc key
sendEscapeKeyPressEvent (widget);
@ -1107,7 +1112,6 @@ bool FApplication::processAccelerator (const FWidget*& widget)
bool FApplication::getMouseEvent()
{
bool mouse_event_occurred = false;
FMouseControl* mouse = getMouseControl();
if ( mouse && mouse->hasData() )
{
@ -1125,8 +1129,6 @@ FWidget*& FApplication::determineClickedWidget()
if ( clicked_widget )
return clicked_widget;
FMouseControl* mouse = getMouseControl();
if ( ! mouse )
return clicked_widget;
@ -1170,8 +1172,6 @@ void FApplication::closeOpenMenu()
{
// Close the open menu
FMouseControl* mouse = getMouseControl();
if ( ! open_menu || ( mouse && mouse->isMoved()) )
return;
@ -1214,8 +1214,6 @@ void FApplication::unselectMenubarItems()
{
// Unselect the menu bar items
FMouseControl* mouse = getMouseControl();
if ( open_menu || (mouse && mouse->isMoved()) )
return;
@ -1258,8 +1256,6 @@ void FApplication::sendMouseEvent()
if ( ! clicked_widget )
return;
FMouseControl* mouse = getMouseControl();
if ( ! mouse )
return;
@ -1298,8 +1294,6 @@ void FApplication::sendMouseMoveEvent ( const FPoint& widgetMousePos
, const FPoint& mouse_position
, int key_state )
{
FMouseControl* mouse = getMouseControl();
if ( ! mouse )
return;
@ -1336,8 +1330,6 @@ void FApplication::sendMouseLeftClickEvent ( const FPoint& widgetMousePos
, const FPoint& mouse_position
, int key_state )
{
FMouseControl* mouse = getMouseControl();
if ( ! mouse )
return;
@ -1378,8 +1370,6 @@ void FApplication::sendMouseRightClickEvent ( const FPoint& widgetMousePos
, const FPoint& mouse_position
, int key_state )
{
FMouseControl* mouse = getMouseControl();
if ( ! mouse )
return;
@ -1412,8 +1402,6 @@ void FApplication::sendMouseMiddleClickEvent ( const FPoint& widgetMousePos
, const FPoint& mouse_position
, int key_state )
{
FMouseControl* mouse = getMouseControl();
if ( ! mouse )
return;
@ -1451,8 +1439,6 @@ void FApplication::sendMouseMiddleClickEvent ( const FPoint& widgetMousePos
void FApplication::sendWheelEvent ( const FPoint& widgetMousePos
, const FPoint& mouse_position )
{
FMouseControl* mouse = getMouseControl();
if ( ! mouse )
return;
@ -1482,8 +1468,6 @@ void FApplication::sendWheelEvent ( const FPoint& widgetMousePos
//----------------------------------------------------------------------
void FApplication::processMouseEvent()
{
FMouseControl* mouse = getMouseControl();
if ( ! getMouseEvent() )
return;