Skip to content

Instantly share code, notes, and snippets.

@vdaghan
Last active February 7, 2022 14:35
Show Gist options
  • Save vdaghan/8cb81bc46cf0f9f91fd81388c17b7498 to your computer and use it in GitHub Desktop.
Save vdaghan/8cb81bc46cf0f9f91fd81388c17b7498 to your computer and use it in GitHub Desktop.
wxTextCtrl as a spdlog sink.
#ifndef LOG_WINDOW_H
#define LOG_WINDOW_H
// Say you have a MyFrame class derived from wxFrame and you want to add a wxWindow to that and use it as a spdlog sink.
// Declaration of your MyFrame class should be like this:
// #include "LogWindow.h"
// class MyFrame: public wxFrame {
// public:
// MyFrame();
// private:
// std::shared_ptr<spdlog::sinks::LogWindow> logWindowPtr;
// std::shared_ptr<spdlog::logger> spdlogger;
// };
// Constructor of your MyFrame should be something like this:
// MyFrame::MyFrame(): wxFrame( NULL, wxID_ANY, "Hello World" ), logWindowPtr( spdlog::sinks::LogWindowPtr( new spdlog::sinks::LogWindow( this ), spdlog::sinks::LogWindowDeleter() ) ), spdlogger( std::make_shared<spdlog::logger>( "wxWidgetsLogger", logWindowPtr ) ) {
// spdlog::register_logger( spdlogger );
// ...
// }
// Then you will be able to use e.g.
// spdlog::get( "wxWidgetsLogger" )->info( "Logger started!" );
// from other parts of your code as soon as MyFrame is constructed.
#include <spdlog/spdlog.h>
#include <spdlog/details/log_msg.h>
#include <spdlog/formatter.h>
#include <spdlog/pattern_formatter.h>
#include <spdlog/sinks/sink.h>
#include <wx/wx.h>
#include <wx/textctrl.h>
#include <memory>
namespace spdlog {
namespace sinks {
class LogWindow: public wxTextCtrl, public sink {
public:
LogWindow( wxWindow * parent ): wxTextCtrl( parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 1024, 768 ), wxTE_MULTILINE | wxTE_READONLY | wxTE_LEFT | wxTE_BESTWRAP | wxBORDER_NONE | wxALWAYS_SHOW_SB ), formatter_( details::make_unique<spdlog::pattern_formatter>() ) {};
~LogWindow() = default;
void log( const details::log_msg & msg ) {
memory_buf_t formatted;
formatter_->format( msg, formatted );
AppendText( std::string( formatted.data(), formatted.size() ) );
ScrollLines( 1 );
};
void flush() { Clear(); };
void set_pattern( const std::string & pattern ) {};
void set_formatter( std::unique_ptr<spdlog::formatter> sink_formatter ) { formatter_ = std::move( sink_formatter ); };
void set_level( level::level_enum log_level ) { level_.store( log_level, std::memory_order_relaxed ); };
level::level_enum level() const { return static_cast<spdlog::level::level_enum>(level_.load( std::memory_order_relaxed )); };
bool should_log( level::level_enum msg_level ) const { return msg_level >= level_.load( std::memory_order_relaxed ); };
protected:
level_t level_{ level::trace };
std::unique_ptr<spdlog::formatter> formatter_;
};
using LogWindowPtr = std::shared_ptr<LogWindow>;
// We need a dummy deleter object to let wxWidgets handle its own memory management
struct LogWindowDeleter {
void operator()( spdlog::sinks::LogWindow * p ) const {};
};
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment