2020-05-13 23:47:14 +02:00
|
|
|
/***********************************************************************
|
|
|
|
* event-log.cpp - Logs events in a dialog box *
|
|
|
|
* *
|
2020-07-08 21:32:47 +02:00
|
|
|
* This file is part of the FINAL CUT widget toolkit *
|
2020-05-13 23:47:14 +02:00
|
|
|
* *
|
2021-03-28 23:19:01 +02:00
|
|
|
* Copyright 2020-2021 Markus Gans *
|
2020-05-13 23:47:14 +02:00
|
|
|
* *
|
2020-07-08 21:32:47 +02:00
|
|
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
|
|
* published by the Free Software Foundation; either version 3 of *
|
2020-05-13 23:47:14 +02:00
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
* *
|
2020-07-08 21:32:47 +02:00
|
|
|
* FINAL CUT is distributed in the hope that it will be useful, but *
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
2020-05-13 23:47:14 +02:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU Lesser General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
|
|
* License along with this program. If not, see *
|
|
|
|
* <http://www.gnu.org/licenses/>. *
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <tuple>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <final/final.h>
|
|
|
|
|
|
|
|
using finalcut::FPoint;
|
|
|
|
using finalcut::FRect;
|
|
|
|
using finalcut::FSize;
|
|
|
|
|
|
|
|
class EventLog; // class forward declaration
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// class EventLog::EventLog
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
class EventDialog final : public finalcut::FDialog
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Constructor
|
|
|
|
explicit EventDialog (finalcut::FWidget* = nullptr);
|
|
|
|
|
|
|
|
// Disable copy constructor
|
|
|
|
EventDialog (const EventDialog&) = delete;
|
|
|
|
|
|
|
|
// Destructor
|
2020-12-03 10:43:20 +01:00
|
|
|
~EventDialog() noexcept override;
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
// Disable copy assignment operator (=)
|
|
|
|
EventDialog& operator = (const EventDialog&) = delete;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Methods
|
2021-03-28 23:19:01 +02:00
|
|
|
void initLayout() override;
|
2020-12-31 20:45:10 +01:00
|
|
|
finalcut::FString getMouseButtonName (const finalcut::MouseButton&) const;
|
2020-05-14 01:22:45 +02:00
|
|
|
void logMouseEvent ( const finalcut::FString&
|
|
|
|
, const finalcut::FMouseEvent& );
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
// Event handlers
|
|
|
|
void onClose (finalcut::FCloseEvent*) override;
|
|
|
|
void onShow (finalcut::FShowEvent*) override;
|
|
|
|
void onTimer (finalcut::FTimerEvent*) override;
|
|
|
|
void onKeyPress (finalcut::FKeyEvent*) override;
|
|
|
|
void onMouseDown (finalcut::FMouseEvent*) override;
|
|
|
|
void onMouseMove (finalcut::FMouseEvent*) override;
|
|
|
|
void onMouseUp (finalcut::FMouseEvent*) override;
|
|
|
|
void onMouseDoubleClick (finalcut::FMouseEvent* ev) override;
|
|
|
|
void onWindowActive (finalcut::FEvent*) override;
|
|
|
|
void onWindowInactive (finalcut::FEvent*) override;
|
|
|
|
void onWindowRaised (finalcut::FEvent*) override;
|
|
|
|
void onWindowLowered (finalcut::FEvent*) override;
|
|
|
|
|
|
|
|
// Data members
|
|
|
|
finalcut::FLog& log{*finalcut::FApplication::getLog()};
|
|
|
|
finalcut::FLabel label{this};
|
|
|
|
};
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
EventDialog::EventDialog (finalcut::FWidget* parent)
|
2020-05-24 23:55:08 +02:00
|
|
|
: FDialog{parent}
|
2020-05-13 23:47:14 +02:00
|
|
|
{
|
|
|
|
setShadow();
|
|
|
|
label.setText("\n\nUse the keyboard or mouse\n"
|
|
|
|
"in this dialog to create events");
|
2020-12-31 20:45:10 +01:00
|
|
|
label.setAlignment(finalcut::Align::Center);
|
2020-05-13 23:47:14 +02:00
|
|
|
addTimer(60000); // Starts the timer every minute
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-12-03 10:43:20 +01:00
|
|
|
EventDialog::~EventDialog() noexcept = default; // destructor
|
2020-05-13 23:47:14 +02:00
|
|
|
|
2021-03-28 23:19:01 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::initLayout()
|
|
|
|
{
|
|
|
|
FDialog::setText ("Event dialog");
|
|
|
|
FDialog::setGeometry (FPoint{15, 2}, FSize{53, 12});
|
|
|
|
label.setGeometry (FPoint(1, 1), getClientSize(), false);
|
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
2020-05-13 23:47:14 +02:00
|
|
|
//----------------------------------------------------------------------
|
2020-12-31 20:45:10 +01:00
|
|
|
finalcut::FString EventDialog::getMouseButtonName (const finalcut::MouseButton& btn_state) const
|
2020-05-13 23:47:14 +02:00
|
|
|
{
|
2020-12-31 20:45:10 +01:00
|
|
|
const auto& empty = finalcut::fc::emptyFString::get();
|
|
|
|
auto S = bool(btn_state & finalcut::MouseButton::Shift);
|
|
|
|
auto C = bool(btn_state & finalcut::MouseButton::Control);
|
|
|
|
auto M = bool(btn_state & finalcut::MouseButton::Meta);
|
|
|
|
auto l = bool(btn_state & finalcut::MouseButton::Left);
|
|
|
|
auto r = bool(btn_state & finalcut::MouseButton::Right);
|
2020-12-31 23:22:22 +01:00
|
|
|
auto m = bool(btn_state & finalcut::MouseButton::Middle);
|
2020-12-31 20:45:10 +01:00
|
|
|
auto prefix = (S ? finalcut::FString("Shift+") : empty)
|
|
|
|
+ (C ? finalcut::FString("Control+") : empty)
|
|
|
|
+ (M ? finalcut::FString("Meta+") : empty);
|
|
|
|
|
|
|
|
if ( l )
|
|
|
|
return prefix + "left";
|
|
|
|
else if ( r )
|
|
|
|
return prefix + "right";
|
|
|
|
else if ( m )
|
|
|
|
return prefix + "middle";
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-05-14 01:22:45 +02:00
|
|
|
void EventDialog::logMouseEvent ( const finalcut::FString& state
|
|
|
|
, const finalcut::FMouseEvent& ev )
|
2020-05-13 23:47:14 +02:00
|
|
|
{
|
|
|
|
const int mouse_x = ev.getX();
|
|
|
|
const int mouse_y = ev.getY();
|
|
|
|
|
2020-12-06 02:11:54 +01:00
|
|
|
log << finalcut::FLog::LogLevel::Info
|
2020-05-13 23:47:14 +02:00
|
|
|
<< getMouseButtonName(ev.getButton())
|
|
|
|
<< " mouse button " << state << " at ("
|
|
|
|
<< mouse_x << ", " << mouse_y << ")" << std::flush;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onClose (finalcut::FCloseEvent* ev)
|
|
|
|
{
|
|
|
|
log.info("The event dialog was closed");
|
|
|
|
ev->accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onShow (finalcut::FShowEvent*)
|
|
|
|
{
|
|
|
|
log.info("The event dialog is now displayed");
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onTimer (finalcut::FTimerEvent*)
|
|
|
|
{
|
|
|
|
log.info("-- minute marker --");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onKeyPress (finalcut::FKeyEvent* ev)
|
|
|
|
{
|
2020-12-31 20:45:10 +01:00
|
|
|
const finalcut::FKey key_id = ev->key();
|
2020-05-16 22:24:36 +02:00
|
|
|
finalcut::FString key_name = finalcut::FTerm::getKeyName(key_id);
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
if ( key_name.isEmpty() )
|
|
|
|
key_name = wchar_t(key_id);
|
|
|
|
|
2020-09-25 00:48:58 +02:00
|
|
|
// std::clog redirects all stream data to FLogger
|
2020-12-06 02:11:54 +01:00
|
|
|
std::clog << finalcut::FLog::LogLevel::Info
|
2020-09-25 00:48:58 +02:00
|
|
|
<< "Key " << key_name
|
2020-12-31 20:45:10 +01:00
|
|
|
<< " (id " << uInt32(key_id) << ")" << std::flush;
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
finalcut::FDialog::onKeyPress(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onMouseDown (finalcut::FMouseEvent* ev)
|
|
|
|
{
|
|
|
|
logMouseEvent("down", *ev);
|
|
|
|
finalcut::FDialog::onMouseDown(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onMouseMove (finalcut::FMouseEvent* ev)
|
|
|
|
{
|
|
|
|
logMouseEvent("move", *ev);
|
|
|
|
finalcut::FDialog::onMouseMove(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onMouseUp (finalcut::FMouseEvent* ev)
|
|
|
|
{
|
|
|
|
logMouseEvent("up", *ev);
|
|
|
|
finalcut::FDialog::onMouseUp(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onMouseDoubleClick (finalcut::FMouseEvent* ev)
|
|
|
|
{
|
|
|
|
logMouseEvent("double click", *ev);
|
|
|
|
finalcut::FDialog::onMouseDoubleClick(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onWindowActive (finalcut::FEvent* ev)
|
|
|
|
{
|
|
|
|
log.info("The Event dialog is now active");
|
|
|
|
finalcut::FDialog::onWindowActive(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onWindowInactive (finalcut::FEvent* ev)
|
|
|
|
{
|
|
|
|
log.info("The Event dialog is now inactive");
|
|
|
|
finalcut::FDialog::onWindowInactive(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onWindowRaised (finalcut::FEvent* ev)
|
|
|
|
{
|
|
|
|
log.info("The dialog was raised");
|
|
|
|
finalcut::FDialog::onWindowRaised(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventDialog::onWindowLowered (finalcut::FEvent* ev)
|
|
|
|
{
|
|
|
|
log.info("The dialog was lowered");
|
|
|
|
finalcut::FDialog::onWindowLowered(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// class EventLog
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
class EventLog final : public finalcut::FDialog, public std::ostringstream
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Constructor
|
|
|
|
explicit EventLog (finalcut::FWidget* = nullptr);
|
|
|
|
|
|
|
|
// Disable copy constructor
|
|
|
|
EventLog (const EventLog&) = delete;
|
|
|
|
|
|
|
|
// Destructor
|
2020-12-03 10:43:20 +01:00
|
|
|
~EventLog() noexcept override;
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
// Disable copy assignment operator (=)
|
|
|
|
EventLog& operator = (const EventLog&) = delete;
|
|
|
|
|
|
|
|
// Event handlers
|
|
|
|
void onTimer (finalcut::FTimerEvent*) override;
|
|
|
|
void onClose (finalcut::FCloseEvent*) override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Method
|
2021-03-28 23:19:01 +02:00
|
|
|
void initLayout() override;
|
2020-05-13 23:47:14 +02:00
|
|
|
void adjustSize() override;
|
|
|
|
|
|
|
|
// Data members
|
2020-09-25 00:48:58 +02:00
|
|
|
finalcut::FTextView scrolltext{this};
|
2020-05-13 23:47:14 +02:00
|
|
|
EventDialog* event_dialog{new EventDialog(this)};
|
|
|
|
};
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
EventLog::EventLog (finalcut::FWidget* parent)
|
2020-05-24 23:55:08 +02:00
|
|
|
: FDialog{parent}
|
2020-05-13 23:47:14 +02:00
|
|
|
{
|
|
|
|
setMinimumSize (FSize{75, 5});
|
|
|
|
setShadow();
|
2020-09-25 00:48:58 +02:00
|
|
|
scrolltext.ignorePadding();
|
2020-05-13 23:47:14 +02:00
|
|
|
event_dialog->setFocus();
|
|
|
|
addTimer(250); // Starts the timer every 250 milliseconds
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-12-03 10:43:20 +01:00
|
|
|
EventLog::~EventLog() noexcept = default; // destructor
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventLog::onTimer (finalcut::FTimerEvent*)
|
|
|
|
{
|
2021-04-05 21:20:02 +02:00
|
|
|
if ( str().empty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
scrolltext.append(str());
|
|
|
|
str("");
|
|
|
|
scrolltext.scrollToEnd();
|
|
|
|
redraw();
|
2020-05-13 23:47:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventLog::onClose (finalcut::FCloseEvent* ev)
|
|
|
|
{
|
|
|
|
finalcut::FApplication::closeConfirmationDialog (this, ev);
|
|
|
|
}
|
|
|
|
|
2021-03-28 23:19:01 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventLog::initLayout()
|
|
|
|
{
|
|
|
|
FDialog::setText ("Event log");
|
|
|
|
FDialog::setGeometry (FPoint{4, 16}, FSize{75, 8});
|
|
|
|
FDialog::setResizeable();
|
|
|
|
scrolltext.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
|
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
2020-05-13 23:47:14 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void EventLog::adjustSize()
|
|
|
|
{
|
|
|
|
finalcut::FDialog::adjustSize();
|
2020-09-25 00:48:58 +02:00
|
|
|
scrolltext.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
|
2020-05-13 23:47:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// main part
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
int main (int argc, char* argv[])
|
|
|
|
{
|
|
|
|
finalcut::FApplication app(argc, argv);
|
|
|
|
EventLog dialog(&app);
|
|
|
|
|
|
|
|
// Get the global logger object
|
|
|
|
finalcut::FLog& log = *finalcut::FApplication::getLog();
|
|
|
|
|
|
|
|
// Set the line endings (default = CRLF)
|
2020-12-06 02:11:54 +01:00
|
|
|
log.setLineEnding (finalcut::FLog::LineEnding::LF);
|
2020-05-13 23:47:14 +02:00
|
|
|
|
|
|
|
// Write a timestamp before each output line
|
|
|
|
log.enableTimestamp();
|
|
|
|
|
|
|
|
// Set the dialog object as output stream
|
|
|
|
log.setOutputStream(dialog);
|
|
|
|
|
|
|
|
// ----------------------------------------------
|
|
|
|
// Remove the comment characters in the following
|
|
|
|
// two lines to log the output to a file.
|
|
|
|
// ----------------------------------------------
|
|
|
|
//std::ofstream file_stream("test.log", std::ofstream::out | std::ofstream::app);
|
|
|
|
//log.setOutputStream(file_stream);
|
|
|
|
|
|
|
|
// Sets the dialog as main widget
|
|
|
|
finalcut::FWidget::setMainWidget(&dialog);
|
|
|
|
|
|
|
|
// Show the dialog
|
|
|
|
dialog.show();
|
|
|
|
|
|
|
|
// Run the application
|
|
|
|
return app.exec();
|
|
|
|
}
|
|
|
|
|