From fff9f63f96919b8b716c272e2cfc982eb8b3215a Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Mon, 15 Nov 2021 21:50:35 +0100 Subject: [PATCH] feat(modulo): implement textview UI --- espanso-modulo/build.rs | 6 + espanso-modulo/src/lib.rs | 1 + espanso-modulo/src/sys/interop/interop.h | 8 + espanso-modulo/src/sys/interop/mod.rs | 11 + espanso-modulo/src/sys/mod.rs | 1 + espanso-modulo/src/sys/textview/mod.rs | 40 ++++ espanso-modulo/src/sys/textview/textview.cpp | 92 ++++++++ espanso-modulo/src/sys/textview/textview.fbp | 223 ++++++++++++++++++ .../src/sys/textview/textview_gui.cpp | 56 +++++ .../src/sys/textview/textview_gui.h | 50 ++++ espanso-modulo/src/textview/mod.rs | 26 ++ 11 files changed, 514 insertions(+) create mode 100644 espanso-modulo/src/sys/textview/mod.rs create mode 100644 espanso-modulo/src/sys/textview/textview.cpp create mode 100644 espanso-modulo/src/sys/textview/textview.fbp create mode 100644 espanso-modulo/src/sys/textview/textview_gui.cpp create mode 100644 espanso-modulo/src/sys/textview/textview_gui.h create mode 100644 espanso-modulo/src/textview/mod.rs diff --git a/espanso-modulo/build.rs b/espanso-modulo/build.rs index 53a995b..f3f1a21 100644 --- a/espanso-modulo/build.rs +++ b/espanso-modulo/build.rs @@ -121,6 +121,8 @@ fn build_native() { .file("src/sys/wizard/wizard_gui.cpp") .file("src/sys/welcome/welcome.cpp") .file("src/sys/welcome/welcome_gui.cpp") + .file("src/sys/textview/textview.cpp") + .file("src/sys/textview/textview_gui.cpp") .file("src/sys/troubleshooting/troubleshooting.cpp") .file("src/sys/troubleshooting/troubleshooting_gui.cpp") .flag("/EHsc") @@ -258,6 +260,8 @@ fn build_native() { .file("src/sys/wizard/wizard_gui.cpp") .file("src/sys/welcome/welcome.cpp") .file("src/sys/welcome/welcome_gui.cpp") + .file("src/sys/textview/textview.cpp") + .file("src/sys/textview/textview_gui.cpp") .file("src/sys/troubleshooting/troubleshooting.cpp") .file("src/sys/troubleshooting/troubleshooting_gui.cpp") .file("src/sys/common/mac.mm"); @@ -452,6 +456,8 @@ fn build_native() { .file("src/sys/wizard/wizard_gui.cpp") .file("src/sys/welcome/welcome.cpp") .file("src/sys/welcome/welcome_gui.cpp") + .file("src/sys/textview/textview.cpp") + .file("src/sys/textview/textview_gui.cpp") .file("src/sys/troubleshooting/troubleshooting.cpp") .file("src/sys/troubleshooting/troubleshooting_gui.cpp"); build.flag("-std=c++17"); diff --git a/espanso-modulo/src/lib.rs b/espanso-modulo/src/lib.rs index afd5396..59ce495 100644 --- a/espanso-modulo/src/lib.rs +++ b/espanso-modulo/src/lib.rs @@ -23,6 +23,7 @@ extern crate lazy_static; pub mod form; pub mod search; mod sys; +pub mod textview; pub mod troubleshooting; pub mod welcome; pub mod wizard; diff --git a/espanso-modulo/src/sys/interop/interop.h b/espanso-modulo/src/sys/interop/interop.h index 2d97c1e..a9510fe 100644 --- a/espanso-modulo/src/sys/interop/interop.h +++ b/espanso-modulo/src/sys/interop/interop.h @@ -168,3 +168,11 @@ typedef struct TroubleshootingMetadata { int (*dont_show_again_changed)(int); int (*open_file)(const char * file_name); } TroubleshootingMetadata; + +// TextView + +typedef struct TextViewMetadata { + const char *window_icon_path; + const char *title; + const char *content; +} TextViewMetadata; diff --git a/espanso-modulo/src/sys/interop/mod.rs b/espanso-modulo/src/sys/interop/mod.rs index debd2b9..e93c878 100644 --- a/espanso-modulo/src/sys/interop/mod.rs +++ b/espanso-modulo/src/sys/interop/mod.rs @@ -189,6 +189,14 @@ pub struct ErrorMetadata { pub message: *const c_char, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TextViewMetadata { + pub window_icon_path: *const c_char, + pub title: *const c_char, + pub content: *const c_char, +} + // Native bindings #[allow(improper_ctypes)] @@ -220,4 +228,7 @@ extern "C" { // TROUBLESHOOTING pub(crate) fn interop_show_troubleshooting(metadata: *const TroubleshootingMetadata); + + // TEXTVIEW + pub(crate) fn interop_show_text_view(metadata: *const TextViewMetadata); } diff --git a/espanso-modulo/src/sys/mod.rs b/espanso-modulo/src/sys/mod.rs index d69b485..490f3ff 100644 --- a/espanso-modulo/src/sys/mod.rs +++ b/espanso-modulo/src/sys/mod.rs @@ -19,6 +19,7 @@ pub mod form; pub mod search; +pub mod textview; pub mod troubleshooting; pub mod welcome; pub mod wizard; diff --git a/espanso-modulo/src/sys/textview/mod.rs b/espanso-modulo/src/sys/textview/mod.rs new file mode 100644 index 0000000..a3213a1 --- /dev/null +++ b/espanso-modulo/src/sys/textview/mod.rs @@ -0,0 +1,40 @@ +/* + * This file is part of modulo. + * + * Copyright (C) 2020-2021 Federico Terzi + * + * modulo is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * modulo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with modulo. If not, see . + */ + +use std::ffi::CString; + +use crate::sys::util::convert_to_cstring_or_null; +use crate::{sys::interop::TextViewMetadata, textview::TextViewOptions}; + +pub fn show(options: TextViewOptions) { + let (_c_window_icon_path, c_window_icon_path_ptr) = + convert_to_cstring_or_null(options.window_icon_path); + let c_title = CString::new(options.title).expect("unable to convert title to CString"); + let c_content = CString::new(options.content).expect("unable to convert content to CString"); + + let textview_metadata = TextViewMetadata { + window_icon_path: c_window_icon_path_ptr, + title: c_title.as_ptr(), + content: c_content.as_ptr(), + }; + + unsafe { + super::interop::interop_show_text_view(&textview_metadata); + } +} diff --git a/espanso-modulo/src/sys/textview/textview.cpp b/espanso-modulo/src/sys/textview/textview.cpp new file mode 100644 index 0000000..7134fbf --- /dev/null +++ b/espanso-modulo/src/sys/textview/textview.cpp @@ -0,0 +1,92 @@ +/* + * This file is part of modulo. + * + * Copyright (C) 2020-2021 Federico Terzi + * + * modulo is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * modulo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with modulo. If not, see . + */ + +#define _UNICODE + +#include "../common/common.h" +#include "../interop/interop.h" +#include "./textview_gui.h" + +#include +#include +#include +#include + +TextViewMetadata *text_view_metadata = nullptr; + +// App Code + +class TextViewApp : public wxApp +{ +public: + virtual bool OnInit(); +}; + +class DerivedTextViewFrame : public TextViewFrame +{ +protected: + void on_copy_to_clipboard( wxCommandEvent& event ); + +public: + DerivedTextViewFrame(wxWindow *parent); +}; + +DerivedTextViewFrame::DerivedTextViewFrame(wxWindow *parent) + : TextViewFrame(parent) +{ + this->text_content->SetValue(wxString::FromUTF8(text_view_metadata->content)); + this->SetTitle(wxString::FromUTF8(text_view_metadata->title)); +} + +void DerivedTextViewFrame::on_copy_to_clipboard( wxCommandEvent& event ) { + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData( new wxTextDataObject(wxString::FromUTF8(text_view_metadata->content)) ); + wxTheClipboard->Close(); + } +} + +bool TextViewApp::OnInit() +{ + DerivedTextViewFrame *frame = new DerivedTextViewFrame(NULL); + + if (text_view_metadata->window_icon_path) + { + setFrameIcon(wxString::FromUTF8(text_view_metadata->window_icon_path), frame); + } + + frame->Show(true); + Activate(frame); + + return true; +} + +extern "C" void interop_show_text_view(TextViewMetadata *_metadata) +{ +// Setup high DPI support on Windows +#ifdef __WXMSW__ + SetProcessDPIAware(); +#endif + + text_view_metadata = _metadata; + + wxApp::SetInstance(new TextViewApp()); + int argc = 0; + wxEntry(argc, (char **)nullptr); +} \ No newline at end of file diff --git a/espanso-modulo/src/sys/textview/textview.fbp b/espanso-modulo/src/sys/textview/textview.fbp new file mode 100644 index 0000000..72bdce5 --- /dev/null +++ b/espanso-modulo/src/sys/textview/textview.fbp @@ -0,0 +1,223 @@ + + + + + ; + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + textview_gui + 1000 + none + + 0 + TextView + + . + #define _UNICODE + 1 + 1 + 1 + 1 + UI + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + wxSYS_COLOUR_WINDOW + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + TextViewFrame + + 895,545 + wxDEFAULT_FRAME_STYLE + ; ; forward_declare + TextView + + + + wxTAB_TRAVERSAL + 1 + + + bSizer1 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,-1,76,0 + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + text_content + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_MULTILINE|wxTE_READONLY + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 10 + wxEXPAND + 0 + + + bSizer2 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 10 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 1 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Copy to Clipboard + + 0 + + 0 + + + 0 + + 1 + copy_to_clipboard_btn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + on_copy_to_clipboard + + + + + + + + diff --git a/espanso-modulo/src/sys/textview/textview_gui.cpp b/espanso-modulo/src/sys/textview/textview_gui.cpp new file mode 100644 index 0000000..60d71ea --- /dev/null +++ b/espanso-modulo/src/sys/textview/textview_gui.cpp @@ -0,0 +1,56 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 26 2018) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#define _UNICODE + +#include "textview_gui.h" + +/////////////////////////////////////////////////////////////////////////// + +TextViewFrame::TextViewFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + wxBoxSizer* bSizer1; + bSizer1 = new wxBoxSizer( wxVERTICAL ); + + text_content = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); + text_content->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + + bSizer1->Add( text_content, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer2; + bSizer2 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer2->Add( 0, 0, 1, wxEXPAND, 5 ); + + copy_to_clipboard_btn = new wxButton( this, wxID_ANY, wxT("Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, 0 ); + + copy_to_clipboard_btn->SetDefault(); + bSizer2->Add( copy_to_clipboard_btn, 0, wxALIGN_CENTER_VERTICAL|wxALL, 10 ); + + + bSizer1->Add( bSizer2, 0, wxEXPAND, 10 ); + + + this->SetSizer( bSizer1 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + copy_to_clipboard_btn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextViewFrame::on_copy_to_clipboard ), NULL, this ); +} + +TextViewFrame::~TextViewFrame() +{ + // Disconnect Events + copy_to_clipboard_btn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextViewFrame::on_copy_to_clipboard ), NULL, this ); + +} diff --git a/espanso-modulo/src/sys/textview/textview_gui.h b/espanso-modulo/src/sys/textview/textview_gui.h new file mode 100644 index 0000000..7c6bfc4 --- /dev/null +++ b/espanso-modulo/src/sys/textview/textview_gui.h @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 26 2018) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class TextViewFrame +/////////////////////////////////////////////////////////////////////////////// +class TextViewFrame : public wxFrame +{ + private: + + protected: + wxTextCtrl* text_content; + wxButton* copy_to_clipboard_btn; + + // Virtual event handlers, overide them in your derived class + virtual void on_copy_to_clipboard( wxCommandEvent& event ) { event.Skip(); } + + + public: + + TextViewFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("TextView"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 895,545 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); + + ~TextViewFrame(); + +}; + diff --git a/espanso-modulo/src/textview/mod.rs b/espanso-modulo/src/textview/mod.rs new file mode 100644 index 0000000..664ba01 --- /dev/null +++ b/espanso-modulo/src/textview/mod.rs @@ -0,0 +1,26 @@ +/* + * This file is part of modulo. + * + * Copyright (C) 2020-2021 Federico Terzi + * + * modulo is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * modulo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with modulo. If not, see . + */ + +pub use crate::sys::textview::show; + +pub struct TextViewOptions { + pub window_icon_path: Option, + pub title: String, + pub content: String, +}