Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development
Help for a plugin newbie - reading keypresses inside the editor
Turbo:
Greetings all,
I've been meaning to try and experiment a bit with extending code::blocks, adding some features to the editor window. Ultimately, if all goes well, i'd like to contribute to the code completion plugin, or create an alternative one with some features such as Netbeans code completion/refactoring features.
I'd like, firstly, to be able to detect when the Control key was pressed while the user is inside the editor, but haven't been able to figure out how.
I've been looking at the code and wiki, but it's not clear how to do this.
What i have so far:
- created a Generic Plugin using the New...Project...CodeBlocks plugin wizard
- added the table event declaration on the .h file with DECLARE_EVENT_TABLE() and associated the event with my callback function (as per wxWidget documentation, and following the byogame plugin code, as it was the only place i could find some keyboard event handling)
BEGIN_EVENT_TABLE(keys,cbPlugin)
EVT_KEY_UP(keys::OnKeyUp)
END_EVENT_TABLE()
like so:
keys.h
--- Code: ---#ifndef KEYS_H_INCLUDED
#define KEYS_H_INCLUDED
// For compilers that support precompilation, includes <wx/wx.h>
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <cbplugin.h> // for "class cbPlugin"
class wxKeyEvent;
class keys : public cbPlugin
{
public:
keys();
virtual ~keys();
virtual void BuildMenu(wxMenuBar* menuBar){}
virtual void BuildModuleMenu(const ModuleType type, wxMenu* menu, const FileTreeData* data = 0){}
virtual bool BuildToolBar(wxToolBar* toolBar){ return false; }
protected:
virtual void OnAttach();
virtual void OnRelease(bool appShutDown);
private:
void OnKeyUp(wxKeyEvent& event);
DECLARE_EVENT_TABLE()
};
#endif // KEYS_H_INCLUDED
--- End code ---
keys.cpp
--- Code: ---#include <sdk.h> // Code::Blocks SDK
#include <configurationpanel.h>
#include "keys.h"
namespace
{
PluginRegistrant<keys> reg(_T("keys"));
}
BEGIN_EVENT_TABLE(keys,cbPlugin)
EVT_KEY_UP(keys::OnKeyUp)
END_EVENT_TABLE()
// constructor
keys::keys()
{
if(!Manager::LoadResource(_T("keys.zip")))
{
NotifyMissingFile(_T("keys.zip"));
}
}
// destructor
keys::~keys()
{
}
void keys::OnAttach()
{
}
void keys::OnRelease(bool appShutDown)
{
}
void keys::OnKeyUp(wxKeyEvent& event)
{
if( !IsAttached() )
return;
Manager::Get()->GetLogManager()->Log( _("key up") );
}
--- End code ---
I expected the releasing of any key to print to the Log Manager, but nothing so far.
Care to help?
blueshake:
--- Code: ---void CodeCompletion::OnAttach()
{
m_PageIndex = -1;
m_InitDone = false;
m_EditMenu = 0;
m_SearchMenu = 0;
m_ViewMenu = 0;
m_Function = 0;
m_Scope = 0;
m_ParsedProjects.clear();
m_FunctionsScope.clear();
m_NameSpaces.clear();
m_AllFunctionsScopes.clear();
m_ToolbarChanged = true; // by default
m_LastFile = wxEmptyString;
LoadTokenReplacements();
RereadOptions();
m_LastPosForCodeCompletion = -1;
m_StartIdxNameSpaceInScope = -1;
m_NativeParser.SetNextHandler(this);
m_NativeParser.CreateClassBrowser();
// hook to editors
EditorHooks::HookFunctorBase* myhook = new EditorHooks::HookFunctor<CodeCompletion>(this, &CodeCompletion::EditorEventHook);
m_EditorHookId = EditorHooks::RegisterHook(myhook);
// register event sinks
Manager* pm = Manager::Get();
pm->RegisterEventSink(cbEVT_EDITOR_SAVE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnReparseActiveEditor));
pm->RegisterEventSink(cbEVT_EDITOR_OPEN, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnEditorOpen));
pm->RegisterEventSink(cbEVT_EDITOR_ACTIVATED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnEditorActivated));
pm->RegisterEventSink(cbEVT_EDITOR_TOOLTIP, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnValueTooltip));
pm->RegisterEventSink(cbEVT_EDITOR_CLOSE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnEditorClosed));
pm->RegisterEventSink(cbEVT_APP_STARTUP_DONE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnAppDoneStartup));
pm->RegisterEventSink(cbEVT_WORKSPACE_CHANGED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnWorkspaceChanged));
pm->RegisterEventSink(cbEVT_PROJECT_ACTIVATE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectActivated));
pm->RegisterEventSink(cbEVT_PROJECT_CLOSE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectClosed));
pm->RegisterEventSink(cbEVT_PROJECT_SAVE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectSaved));
pm->RegisterEventSink(cbEVT_PROJECT_FILE_ADDED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectFileAdded));
pm->RegisterEventSink(cbEVT_PROJECT_FILE_REMOVED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectFileRemoved));
}
--- End code ---
It seems use this way to register event.Not sure about it.
dmoore:
--- Quote from: Turbo on December 06, 2009, 08:26:07 pm ---I expected the releasing of any key to print to the Log Manager, but nothing so far.
Care to help?
--- End quote ---
what you are doing with your event table is telling wxWidgets you want to capture key events from your plugin and any of its children. one problem: your plugin is not the parent of the editors.
read this blog post: http://wxwidgets.blogspot.com/2007/01/in-praise-of-connect.html
Turbo:
blueshake, after your reply, i went and dove into the code and tried to make some sense of it. Before noticing dmoore's reply, i came up with the following:
My OnAttach is now:
--- Code: ---void keys::OnAttach()
{
// hook events to editors
EditorHooks::HookFunctorBase* myhook = new EditorHooks::HookFunctor<keys>(this, &keys::EditorEventHook);
this->m_EditorHookId = EditorHooks::RegisterHook(myhook);
}
--- End code ---
and "keys::EditorEventHook":
--- Code: ---void keys::EditorEventHook(cbEditor* editor, wxScintillaEvent& event)
{
wxString str(_T("keys::EditorEventHook:"));
str += _(" event type:");
std::stringstream ss;
ss << event.GetEventType();
str += wxString(ss.str().c_str(), wxConvUTF8);
str += _(" event key:");
ss.str("");
ss << event.GetKey();
str += wxString(ss.str().c_str(), wxConvUTF8);
Manager::Get()->GetLogManager()->Log(str);
// if(event.GetEventType() == wxEVT_SCI_KEY)
// Manager::Get()->GetLogManager()->Log(_("key event type"));
if(event.GetControl())
Manager::Get()->GetLogManager()->Log(_("ctrl"));
if(event.GetKey() == wxSCI_KEY_UP)
Manager::Get()->GetLogManager()->Log(_("key up event"));
if(event.GetKey() == wxSCI_KEY_DOWN)
Manager::Get()->GetLogManager()->Log(_("key down event"));
//if(event.GetEventType() == wxEVT_CHAR)
// Manager::Get()->GetLogManager()->Log(_("key character event"));
// allow others to handle this event
event.Skip();
}
--- End code ---
I've managed to receive and print a few wxScintillaEvents, but i haven't been able to make much sense of them (no correspondance with the defines in wx/wxScintilla.h). Like a keypress will activate 5 or 6 events in the 10300 to 10*** range.
event.GetKey() is always 0, so none of those messages are printed.
If I leave the "if(event.GetControl())" line, i get an "undefined reference to `_imp___ZNK16wxScintillaEvent10GetControlEv' in keys.cpp :|
In the same way, if i leave the "wxEVT_SCI_KEY" check, i get another unexpected linker error...
The code looks nicely organized, but it's a bit overwhelming to the newbie, lots of different libraries mixed together and not many comments in the code make it a bit hard to follow.
I will try your suggestion later tomorrow, dmoore. Thank you for your help. If you have any idea on why i have the above problems, please share.
dmoore:
did you try looking at void CodeCompletion::EditorEventHook(cbEditor* editor, wxScintillaEvent& event) in src/plugins/codecompletion/codecompletion.cpp (approx line 1850)?
Navigation
[0] Message Index
[#] Next page
Go to full version