18#include <wx/dcmemory.h>
19#include <wx/clipbrd.h>
22#include "../../RefreshCode.h"
31 return keyCode < WXK_START ||
32 (keyCode >= WXK_END && keyCode < WXK_UP) ||
33 (keyCode == WXK_RIGHT) ||
34 (keyCode >= WXK_NUMPAD0 && keyCode <= WXK_DIVIDE) ||
35 (keyCode >= WXK_NUMPAD_SPACE && keyCode <= WXK_NUMPAD_ENTER) ||
36 (keyCode >= WXK_NUMPAD_HOME && keyCode <= WXK_NUMPAD_END) ||
37 (keyCode >= WXK_NUMPAD_DELETE && keyCode <= WXK_NUMPAD_DIVIDE) ||
39 (keyCode > WXK_RAW_CONTROL) ||
41 (keyCode > WXK_WINDOWS_MENU);
66 lock->OnTextEditCancelled(
project);
99 return mods == wxMOD_NONE || mods == wxMOD_SHIFT;
131 if (((
int)wchar > 0xDFFF) || ((
int)wchar < 0xDC00))
146 case WXK_NUMPAD_DELETE:
148 int len =
mText.length();
161 if (((
int)wchar > 0xDBFF) || ((
int)wchar < 0xD800))
176 case WXK_NUMPAD_HOME:
179 if (mods == wxMOD_SHIFT)
188 if (mods == wxMOD_SHIFT)
195 case WXK_NUMPAD_LEFT:
205 more = !(((int)wchar > 0xDFFF) || ((int)wchar < 0xDC00));
209 if (mods != wxMOD_SHIFT)
215 case WXK_NUMPAD_RIGHT:
225 more = !(((int)wchar > 0xDBFF) || ((int)wchar < 0xD800));
229 if (mods != wxMOD_SHIFT)
236 delegate->OnTextEditCancelled(
project);
239 case WXK_NUMPAD_ENTER:
253 if (charCode == 0 || wxIscntrl(charCode)) {
285 if (event.ButtonDown())
288 if (
mBBox.Contains(event.GetPosition()))
290 if (event.LeftDown())
295 if (event.ShiftDown()) {
300 if (abs(position - current) > abs(position - initial))
324#if defined(__WXGTK__) && (HAVE_GTK)
325 if (evt.MiddleDown()) {
327 wxTheClipboard->UsePrimarySelection(
true);
328 view.PasteSelectedText(
project, newSel.t0(), newSel.t1());
329 wxTheClipboard->UsePrimarySelection(
false);
355 const auto cursorHeight = dc.GetFontMetrics().height;
359 wxDCClipper clipper(dc, rect);
362 auto maxOffset =
static_cast<int>(
mText.Length());
366 const auto rtl = wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft;
368 auto leftBound = rect.GetLeft();
369 auto rightBound = rect.GetRight() + 1;
372 if ((!rtl && curPosX >= rightBound) || (rtl && curPosX < leftBound))
377 if (curPosX < rightBound && curPosX >= leftBound)
382 if ((!rtl && curPosX < leftBound) || (rtl && curPosX >= rightBound))
387 if (curPosX >= leftBound && curPosX < rightBound)
403 dc.SetPen(*wxTRANSPARENT_PEN);
405 dc.DrawRectangle(wxRect(left, rect.GetTop() + (rect.GetHeight() - cursorHeight) / 2, right - left, cursorHeight));
409 dc.SetTextBackground(wxTransparentColour);
411 dc.SetFont(wxFont(wxFontInfo()));
412 dc.DrawLabel(
mText.Mid(
mOffset), rect, (rtl ? wxALIGN_RIGHT : wxALIGN_LEFT) | wxALIGN_CENTER_VERTICAL);
423 auto top = rect.GetTop() + (rect.GetHeight() - cursorHeight) / 2;
424 dc.DrawLine(curPosX, top, curPosX, top + cursorHeight);
431 if (event.Dragging())
439 else if (event.RightUp() &&
mBBox.Contains(event.GetPosition()))
446 delegate->OnTextContextMenu(
project, event.GetPosition());
459 wxString left, right;
467 left =
mText.Left(init);
469 if (cur < (
int)
mText.length())
470 right =
mText.Mid(cur);
472 mText = left + right;
487 bool finished =
false;
496 offsetX = dc.GetTextExtent(
mText.Left(
mOffset)).GetWidth();
498 const auto layout = wxTheApp->GetLayoutDirection();
500 const int length =
mText.length();
501 while (!finished && (charIndex < length + 1))
503 int unichar = (int)
mText.at(charIndex - 1);
504 if ((0xDC00 <= unichar) && (unichar <= 0xDFFF)) {
508 subString =
mText.Left(charIndex);
510 dc.GetTextExtent(subString, &partWidth, NULL);
513 dc.GetTextExtent(subString.Right(1), &oneWidth, NULL);
515 if (layout == wxLayout_RightToLeft)
517 auto bound =
mBBox.GetRight() - partWidth + offsetX + oneWidth / 2;
518 if (point.x >= bound)
520 result = charIndex - 1;
526 auto bound =
mBBox.GetLeft() + partWidth - offsetX - oneWidth / 2;
527 if (point.x <= bound)
529 result = charIndex - 1;
556 offsetX = dc.GetTextExtent(
mText.Left(
mOffset)).GetWidth();
559 if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft)
562 *outX =
mBBox.GetRight() + offsetX;
564 *outX =
mBBox.GetRight() - dc.GetTextExtent(
mText.Left(index)).GetWidth() + offsetX;
569 *outX =
mBBox.GetLeft() - offsetX;
571 *outX =
mBBox.GetLeft() + dc.GetTextExtent(
mText.Left(index)).GetWidth() - offsetX;
598 wxString left, right;
600 wxString data =
mText.Mid(init, cur - init);
604 left =
mText.Left(init);
607 if (cur < (
int)
mText.length())
608 right =
mText.Mid(cur);
611 mText = left + right;
615 if (wxTheClipboard->Open()) {
617 wxTheClipboard->SetData(
safenew wxTextDataObject(data));
618 wxTheClipboard->Close();
643 wxString data =
mText.Mid(init, cur - init);
646 if (wxTheClipboard->Open()) {
648 wxTheClipboard->SetData(
safenew wxTextDataObject(data));
649 wxTheClipboard->Close();
664 wxString text, left, right;
667 if (wxTheClipboard->IsSupported(wxDF_UNICODETEXT))
669 if (wxTheClipboard->Open()) {
670 wxTextDataObject data;
671 wxTheClipboard->GetData(data);
672 wxTheClipboard->Close();
673 text = data.GetText();
677 for (
int i = 0; i < (int)text.length(); i++) {
678 if (wxIscntrl(text[i])) {
688 left =
mText.Left(init);
689 if (cur < (
int)
mText.length())
690 right =
mText.Mid(cur);
692 mText = left + text + right;
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
virtual ~TextEditDelegate()
bool HandleDragRelease(const wxMouseEvent &event, AudacityProject *project)
void SetTextSelectionColor(const wxColor &textSelectionColor)
bool OnChar(int charCode, AudacityProject *project)
bool OnDrag(const wxMouseEvent &event, AudacityProject *project)
static bool IsGoodEditKeyCode(int keyCode)
bool OnKeyDown(int keyCode, int mods, AudacityProject *project)
void Finish(AudacityProject *project)
bool OnClick(const wxMouseEvent &event, AudacityProject *project)
bool CaptureKey(int keyCode, int mods)
int FindCursorIndex(const wxPoint &point)
bool CutSelectedText(AudacityProject &project)
bool GetCharPositionX(int index, int *outX)
bool Draw(wxDC &dc, const wxRect &rect)
void RemoveSelectedText(AudacityProject *project)
const wxRect & GetBBox() const
TextEditHelper(const std::weak_ptr< TextEditDelegate > &delegate, const wxString &text, const wxFont &font)
void SetSelection(int from, int to)
bool PasteSelectedText(AudacityProject &project)
bool OnRelease(const wxMouseEvent &event, AudacityProject *project)
void SetTextColor(const wxColor &textColor)
bool CopySelectedText(AudacityProject &project)
void Cancel(AudacityProject *project)
std::pair< int, int > GetSelection() const
wxColor mTextSelectionColor
std::weak_ptr< TextEditDelegate > mDelegate
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)