📄 scintillawx.cpp
字号:
////////////////////////////////////////////////////////////////////////////
// Name: ScintillaWX.cxx
// Purpose: A wxWidgets implementation of Scintilla. A class derived
// from ScintillaBase that uses the "wx platform" defined in
// PlatformWX.cxx This class is one end of a bridge between
// the wx world and the Scintilla world. It needs a peer
// object of type wxStyledTextCtrl to function.
//
// Author: Robin Dunn
//
// Created: 13-Jan-2000
// RCS-ID: $Id: ScintillaWX.cpp,v 1.94 2006/07/13 00:18:04 RD Exp $
// Copyright: (c) 2000 by Total Control Software
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#include "wx/wx.h"
#include "wx/textbuf.h"
#include "wx/dataobj.h"
#include "wx/clipbrd.h"
#include "wx/dnd.h"
#include "ScintillaWX.h"
#include "ExternalLexer.h"
#include "wx/stc/stc.h"
#include "PlatWX.h"
#ifdef __WXMSW__
// GetHwndOf()
#include "wx/msw/private.h"
#endif
//----------------------------------------------------------------------
// Helper classes
class wxSTCTimer : public wxTimer {
public:
wxSTCTimer(ScintillaWX* swx) {
this->swx = swx;
}
void Notify() {
swx->DoTick();
}
private:
ScintillaWX* swx;
};
#if wxUSE_DRAG_AND_DROP
class wxStartDragTimer : public wxTimer {
public:
wxStartDragTimer(ScintillaWX* swx) {
this->swx = swx;
}
void Notify() {
swx->DoStartDrag();
}
private:
ScintillaWX* swx;
};
bool wxSTCDropTarget::OnDropText(wxCoord x, wxCoord y, const wxString& data) {
return swx->DoDropText(x, y, data);
}
wxDragResult wxSTCDropTarget::OnEnter(wxCoord x, wxCoord y, wxDragResult def) {
return swx->DoDragEnter(x, y, def);
}
wxDragResult wxSTCDropTarget::OnDragOver(wxCoord x, wxCoord y, wxDragResult def) {
return swx->DoDragOver(x, y, def);
}
void wxSTCDropTarget::OnLeave() {
swx->DoDragLeave();
}
#endif // wxUSE_DRAG_AND_DROP
#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
#include <wx/popupwin.h>
#define wxSTCCallTipBase wxPopupWindow
#define param2 wxBORDER_NONE // popup's 2nd param is flags
#else
#define wxSTCCallTipBase wxWindow
#define param2 -1 // wxWindow's 2nd param is ID
#endif
#include <wx/dcbuffer.h>
class wxSTCCallTip : public wxSTCCallTipBase {
public:
wxSTCCallTip(wxWindow* parent, CallTip* ct, ScintillaWX* swx)
: wxSTCCallTipBase(parent, param2),
m_ct(ct), m_swx(swx), m_cx(wxDefaultCoord), m_cy(wxDefaultCoord)
{
}
~wxSTCCallTip() {
#if wxUSE_POPUPWIN && wxSTC_USE_POPUP && defined(__WXGTK__)
wxRect rect = GetRect();
rect.x = m_cx;
rect.y = m_cy;
GetParent()->Refresh(false, &rect);
#endif
}
bool AcceptsFocus() const { return false; }
void OnPaint(wxPaintEvent& WXUNUSED(evt)) {
wxBufferedPaintDC dc(this);
Surface* surfaceWindow = Surface::Allocate();
surfaceWindow->Init(&dc, m_ct->wDraw.GetID());
m_ct->PaintCT(surfaceWindow);
surfaceWindow->Release();
delete surfaceWindow;
}
void OnFocus(wxFocusEvent& event) {
GetParent()->SetFocus();
event.Skip();
}
void OnLeftDown(wxMouseEvent& event) {
wxPoint pt = event.GetPosition();
Point p(pt.x, pt.y);
m_ct->MouseClick(p);
m_swx->CallTipClick();
}
#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
virtual void DoSetSize(int x, int y,
int width, int height,
int sizeFlags = wxSIZE_AUTO) {
if (x != wxDefaultCoord) {
m_cx = x;
GetParent()->ClientToScreen(&x, NULL);
}
if (y != wxDefaultCoord) {
m_cy = y;
GetParent()->ClientToScreen(NULL, &y);
}
wxSTCCallTipBase::DoSetSize(x, y, width, height, sizeFlags);
}
#endif
wxPoint GetMyPosition() {
return wxPoint(m_cx, m_cy);
}
private:
CallTip* m_ct;
ScintillaWX* m_swx;
int m_cx, m_cy;
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxSTCCallTip, wxSTCCallTipBase)
EVT_PAINT(wxSTCCallTip::OnPaint)
EVT_SET_FOCUS(wxSTCCallTip::OnFocus)
EVT_LEFT_DOWN(wxSTCCallTip::OnLeftDown)
END_EVENT_TABLE()
//----------------------------------------------------------------------
#if wxUSE_DATAOBJ
static wxTextFileType wxConvertEOLMode(int scintillaMode)
{
wxTextFileType type;
switch (scintillaMode) {
case wxSTC_EOL_CRLF:
type = wxTextFileType_Dos;
break;
case wxSTC_EOL_CR:
type = wxTextFileType_Mac;
break;
case wxSTC_EOL_LF:
type = wxTextFileType_Unix;
break;
default:
type = wxTextBuffer::typeDefault;
break;
}
return type;
}
#endif // wxUSE_DATAOBJ
//----------------------------------------------------------------------
// Constructor/Destructor
ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
capturedMouse = false;
focusEvent = false;
wMain = win;
stc = win;
wheelRotation = 0;
Initialise();
#ifdef __WXMSW__
sysCaretBitmap = 0;
sysCaretWidth = 0;
sysCaretHeight = 0;
#endif
#if wxUSE_DRAG_AND_DROP
startDragTimer = new wxStartDragTimer(this);
#endif // wxUSE_DRAG_AND_DROP
}
ScintillaWX::~ScintillaWX() {
#if wxUSE_DRAG_AND_DROP
delete startDragTimer;
#endif // wxUSE_DRAG_AND_DROP
Finalise();
}
//----------------------------------------------------------------------
// base class virtuals
void ScintillaWX::Initialise() {
//ScintillaBase::Initialise();
#if wxUSE_DRAG_AND_DROP
dropTarget = new wxSTCDropTarget;
dropTarget->SetScintilla(this);
stc->SetDropTarget(dropTarget);
#endif // wxUSE_DRAG_AND_DROP
#ifdef __WXMAC__
vs.extraFontFlag = false; // UseAntiAliasing
#else
vs.extraFontFlag = true; // UseAntiAliasing
#endif
}
void ScintillaWX::Finalise() {
ScintillaBase::Finalise();
SetTicking(false);
SetIdle(false);
DestroySystemCaret();
}
void ScintillaWX::StartDrag() {
#if wxUSE_DRAG_AND_DROP
// We defer the starting of the DnD, otherwise the LeftUp of a normal
// click could be lost and the STC will think it is doing a DnD when the
// user just wanted a normal click.
startDragTimer->Start(200, true);
#endif // wxUSE_DRAG_AND_DROP
}
void ScintillaWX::DoStartDrag() {
#if wxUSE_DRAG_AND_DROP
wxString dragText = stc2wx(drag.s, drag.len);
// Send an event to allow the drag text to be changed
wxStyledTextEvent evt(wxEVT_STC_START_DRAG, stc->GetId());
evt.SetEventObject(stc);
evt.SetDragText(dragText);
evt.SetDragAllowMove(true);
evt.SetPosition(wxMin(stc->GetSelectionStart(),
stc->GetSelectionEnd()));
stc->GetEventHandler()->ProcessEvent(evt);
dragText = evt.GetDragText();
if (dragText.length()) {
wxDropSource source(stc);
wxTextDataObject data(dragText);
wxDragResult result;
source.SetData(data);
dropWentOutside = true;
result = source.DoDragDrop(evt.GetDragAllowMove());
if (result == wxDragMove && dropWentOutside)
ClearSelection();
inDragDrop = false;
SetDragPosition(invalidPosition);
}
#endif // wxUSE_DRAG_AND_DROP
}
bool ScintillaWX::SetIdle(bool on) {
if (idler.state != on) {
// connect or disconnect the EVT_IDLE handler
if (on)
stc->Connect(wxID_ANY, wxEVT_IDLE,
(wxObjectEventFunction) (wxEventFunction) (wxIdleEventFunction) &wxStyledTextCtrl::OnIdle);
else
stc->Disconnect(wxID_ANY, wxEVT_IDLE,
(wxObjectEventFunction) (wxEventFunction) (wxIdleEventFunction) &wxStyledTextCtrl::OnIdle);
idler.state = on;
}
return idler.state;
}
void ScintillaWX::SetTicking(bool on) {
wxSTCTimer* steTimer;
if (timer.ticking != on) {
timer.ticking = on;
if (timer.ticking) {
steTimer = new wxSTCTimer(this);
steTimer->Start(timer.tickSize);
timer.tickerID = steTimer;
} else {
steTimer = (wxSTCTimer*)timer.tickerID;
steTimer->Stop();
delete steTimer;
timer.tickerID = 0;
}
}
timer.ticksToWait = caret.period;
}
void ScintillaWX::SetMouseCapture(bool on) {
if (mouseDownCaptures) {
if (on && !capturedMouse)
stc->CaptureMouse();
else if (!on && capturedMouse && stc->HasCapture())
stc->ReleaseMouse();
capturedMouse = on;
}
}
bool ScintillaWX::HaveMouseCapture() {
return capturedMouse;
}
void ScintillaWX::ScrollText(int linesToMove) {
int dy = vs.lineHeight * (linesToMove);
stc->ScrollWindow(0, dy);
stc->Update();
}
void ScintillaWX::SetVerticalScrollPos() {
if (stc->m_vScrollBar == NULL) { // Use built-in scrollbar
stc->SetScrollPos(wxVERTICAL, topLine);
}
else { // otherwise use the one that's been given to us
stc->m_vScrollBar->SetThumbPosition(topLine);
}
}
void ScintillaWX::SetHorizontalScrollPos() {
if (stc->m_hScrollBar == NULL) { // Use built-in scrollbar
stc->SetScrollPos(wxHORIZONTAL, xOffset);
}
else { // otherwise use the one that's been given to us
stc->m_hScrollBar->SetThumbPosition(xOffset);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -