From eb8ae63b72e72a1650b062676d3ec8a4fbba7445 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Tue, 25 Dec 2018 22:34:04 +0100 Subject: [PATCH] Add a "event processing" chapter into the first steps document --- ChangeLog | 7 +- doc/first-steps.md | 176 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 177 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 14d11e6b..3e666633 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,13 @@ +2018-12-25 Markus Gans + * Add a "event processing" chapter into the first steps document + 2018-12-24 Markus Gans * Events can not only be sent to FWidgets, but also to FObjects * New event FUserEvent for user-defined events 2018-12-19 Markus Gans * Use of smart pointers - * Add a "memory management" Chapter into the first steps document + * Add a "memory management" chapter into the first steps document 2018-12-17 Markus Gans * Improve FButton mouse click animation @@ -13,7 +16,7 @@ 2018-12-15 Markus Gans * Use of the C++11 auto specifier in the program code - * Code reduction by using of Range-based for loop + * Code reduction by using of range-based for loop * The example program for video attributes now replaces the switch statement with a vector of lambda expressions diff --git a/doc/first-steps.md b/doc/first-steps.md index 629cd6e4..f10ca8c2 100644 --- a/doc/first-steps.md +++ b/doc/first-steps.md @@ -101,7 +101,7 @@ not closed. Memory Management ----------------- -If you want to create a hierarchy of FObjects (or derived classes/widgets), +To create a hierarchy of FObjects (or derived classes/widgets), a new FObject must initialize with its parent object. ```cpp @@ -109,9 +109,8 @@ FObject* parent = new FObject(); FObject* child = new FObject(parent); ``` -When you deallocate the used memory of a parent FObject, -the allocated memory of its child objects will automatically deallocate -too. +To deallocate the used memory of a parent FObject, the allocated memory +of its child objects will also automatically deallocate. An object can also be assigned to another object later via `addChild()`. @@ -134,3 +133,172 @@ If an FObject with a parent will remove from the hierarchy, the destructor automatically deletes the object assignment from its parent object. If a class object doesn't derive from FObject, you must implement storage deallocation yourself. + +**File:** *memory.cpp* +```cpp +#include + +using namespace finalcut; + +int main (int argc, char* argv[]) +{ + FApplication app(argc, argv); + + // The object dialog is managed by app + FDialog* dialog = new FDialog(&app); + dialog->setText ("Window Title"); + dialog->setGeometry (25, 5, 40, 8); + + // The object input is managed by dialog + FLineEdit* input = new FLineEdit("predefined text", dialog); + input->setGeometry(8, 2, 29, 1); + input->setLabelText (L"&Input"); + + // The object label is managed by dialog + FLabel* label = new FLabel ( "Lorem ipsum dolor sit amet, consectetur " + "adipiscing elit, sed do eiusmod tempor " + "incididunt ut labore et dolore magna aliqua." + , dialog ); + label->setGeometry (2, 4, 36, 1); + app.setMainWidget(dialog); + dialog->show(); + return app.exec(); +} +``` +*(Note: You can close the window with the mouse, +Shift+F10 or Ctrl+^)* + + +After entering the source code in *memory.cpp* you can compile +the above program with gcc: +```cpp +g++ -O2 -lfinal memory.cpp -o memory +``` + + +Event Processing +---------------- + +Calling `FApplication::exec()` starts the FINAL CUT main event loop. +While the event loop is running, the system constantly checks whether +an event has occurred and sends it to the application's currently focused +object. The events of the terminal such as keystrokes, mouse actions or +resizing the terminal are translated into `FEvent` objects and sent it to +the active `FObject`. It is also possible to use `FApplication::sendEvent()` +or `FApplication::queueEvent()` to send your own events to an object. + +`FObject`-derived objects process incoming events by reimplementing the +virtual method `event()`. The `FObject` itself calls only +`onTimer()` or `onUserEvent()` and ignores all other events. The +`FObject`-derived class `FWidget` also reimplements the `event()` method +to handle further events. `FWidget` calls the `FWidget::onKeyPress` method +when you press a key, or the `FWidget::onMouseDown` method when you click +a mouse button. + + +### Event handler reimplementation ### + +An event in FINAL CUT is an object that inherits from the base class +`FEvent`. There are several event types, represented by an enum value. +For example, the method `FEvent::type()` returns the type +`fc::MouseDown_Event` when you press down a mouse button. + +Some event types have data that cannot store in an `FEvent` object. +For example, a click event of the mouse must store which button it +triggered where the mouse pointer was at that time. In classes derived +from `FEvent`, such as `FMouseEvent()`, we store this data. + +Widgets get their events from the `event()` method inherited from FObject. +The implementation of `event()` in `FWidget` forwards the most common event +types to specific event handlers such as `FMouseEvent()`, `FKeyEvent()` or +`FResizeEvent()`. There are many other event types. It is also possible to +create own event types and send them to other objects. + + +**The FINAL CUT event types:** +```cpp +enum events +{ + None_Event, // invalid event + KeyPress_Event, // key pressed + KeyUp_Event, // key released + KeyDown_Event, // key pressed + MouseDown_Event, // mouse button pressed + MouseUp_Event, // mouse button released + MouseDoubleClick_Event, // mouse button double click + MouseWheel_Event, // mouse wheel rolled + MouseMove_Event, // mouse move + FocusIn_Event, // focus in + FocusOut_Event, // focus out + ChildFocusIn_Event, // child focus in + ChildFocusOut_Event, // child focus out + WindowActive_Event, // activate window + WindowInactive_Event, // deactivate window + WindowRaised_Event, // raise window + WindowLowered_Event, // lower window + Accelerator_Event, // keyboard accelerator + Resize_Event, // terminal resize + Show_Event, // widget is shown + Hide_Event, // widget is hidden + Close_Event, // widget close + Timer_Event, // timer event occur + User_Event // user defined event +}; +``` + + +**File:** *timer.cpp* +```cpp +#include + +using namespace finalcut; + +class dialogWidget : public FDialog +{ + public: + explicit dialogWidget (FWidget* parent = nullptr) + : FDialog(parent) + { + setText ("Dialog"); + setGeometry (25, 5, 23, 4); + label.setGeometry (1, 1, 10, 1); + label.setAlignment (fc::alignRight); + value.setGeometry (11, 1, 10, 1); + id = addTimer(100); + } + + private: + virtual void onTimer (FTimerEvent* ev) + { + if ( id == ev->getTimerId() && n < 9999999999 ) + { + value.setNumber(n); + value.redraw(); + n++; + } + } + + FLabel label{"Counter: ", this}; + FLabel value{"0", this}; + long n{0}; + int id{0}; +}; + +int main (int argc, char* argv[]) +{ + FApplication app(argc, argv); + dialogWidget dialog(&app); + app.setMainWidget(&dialog); + dialog.show(); + return app.exec(); +} +``` +*(Note: You can close the window with the mouse, +Shift+F10 or Ctrl+^)* + + +After entering the source code in *timer.cpp* you can compile +the above program with gcc: +```cpp +g++ -O2 -std=c++11 -lfinal timer.cpp -o timer +```