1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#pragma once
#include <functional>
#include <wx/textctrl.h>
namespace wxutil
{
/**
* A special entry field keeping track of focus events and editing status.
* The attached callbacks ("apply" and "cancel") are automatically invoked
* where appropriate (losing focus, pressing enter or escape, etc.)
*/
class NonModalEntry :
public wxTextCtrl
{
public:
typedef std::function<void()> ApplyCallback;
typedef std::function<void()> CancelCallback;
typedef std::function<void()> ChangedCallback;
private:
bool _editing;
ApplyCallback _apply;
CancelCallback _cancel;
ChangedCallback _changed;
bool _giveUpFocusOnApplyOrCancel;
public:
NonModalEntry(wxWindow* parent, const ApplyCallback& apply, const CancelCallback& cancel,
const ChangedCallback& changed = 0,
bool giveUpFocusOnApplyOrCancel = true) :
wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER),
_editing(false),
_apply(apply),
_cancel(cancel),
_changed(changed),
_giveUpFocusOnApplyOrCancel(giveUpFocusOnApplyOrCancel)
{
Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(NonModalEntry::onGetFocus), NULL, this);
Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(NonModalEntry::onLoseFocus), NULL, this);
Connect(wxEVT_TEXT, wxCommandEventHandler(NonModalEntry::onTextChanged), NULL, this);
Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(NonModalEntry::onTextEntryKeyPressed), NULL, this);
}
protected:
void onGetFocus(wxFocusEvent& ev)
{
_editing = false;
ev.Skip();
}
void onLoseFocus(wxFocusEvent& ev)
{
if (_editing && IsShown())
{
if (_apply)
{
_apply();
}
}
_editing = false;
ev.Skip();
}
void onTextChanged(wxCommandEvent& ev)
{
_editing = true;
if (IsShown())
{
if (_changed)
{
_changed();
}
}
ev.Skip();
}
void onTextEntryKeyPressed(wxKeyEvent& ev)
{
if (ev.GetKeyCode() == WXK_RETURN || ev.GetKeyCode() == WXK_ESCAPE)
{
if (ev.GetKeyCode() == WXK_RETURN)
{
if (_apply)
{
_apply();
}
}
else
{
if (_cancel)
{
_cancel();
}
}
_editing = false;
if (_giveUpFocusOnApplyOrCancel)
{
wxWindow* parent = GetParent();
while (parent != NULL && parent->GetParent() != NULL)
{
parent = parent->GetParent();
}
if (parent != NULL)
{
parent->SetFocus();
}
}
return;
}
ev.Skip();
}
};
} // namespace
|