18#if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
22#if defined(SK_FONTMGR_CORETEXT_AVAILABLE)
26#if defined(SK_FONTMGR_DIRECTWRITE_AVAILABLE)
37#ifdef SK_EDITOR_DEBUG_OUT
40 #define M(X) case skui::Key::k ## X: return #X
41 M(NONE);
M(LeftSoftKey);
M(RightSoftKey);
M(Home);
M(Back);
M(Send);
M(End);
M(0);
M(1);
42 M(2);
M(3);
M(4);
M(5);
M(6);
M(7);
M(8);
M(9);
M(Star);
M(Hash);
M(Up);
M(Down);
M(Left);
43 M(Right);
M(Tab);
M(PageUp);
M(PageDown);
M(Delete);
M(Escape);
M(Shift);
M(Ctrl);
53 #define M(X) if (m & skui::ModifierKey::k ## X ##) { s.append(" {" #X "}"); }
54 M(Shift)
M(Control)
M(
Option)
M(Command)
M(FirstPress)
61 if ((
unsigned)c < 0x100) {
62 SkDebugf(
"char: %c (0x%02X)%s\n", (
char)(c & 0xFF), (
unsigned)c,
m.c_str());
64 SkDebugf(
"char: 0x%08X%s\n", (
unsigned)c,
m.c_str());
69 SkDebugf(
"key: %s%s\n", key_name(
key), modifiers_desc(modi).c_str());
94static const char* kTypefaces[3] = {
"sans-serif",
"serif",
"monospace"};
95static constexpr size_t kTypefaceCount = std::size(kTypefaces);
103 static bool init =
false;
106#if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
108#elif defined(SK_FONTMGR_CORETEXT_AVAILABLE)
110#elif defined(SK_FONTMGR_DIRECTWRITE_AVAILABLE)
111 fontMgr = SkFontMgr_New_DirectWrite();
126 std::vector<char> fClipboard;
128 Editor::TextPosition fTextPos{0, 0};
129 Editor::TextPosition fMarkPos;
134 size_t fTypefaceIndex = 0;
136 bool fShiftDown =
false;
138 bool fMouseDown =
false;
146 void loadFile(
const char* path) {
149 fEditor.
insert(Editor::TextPosition{0, 0},
150 (
const char*)
data->data(),
data->size());
152 fPath =
"output.txt";
160 canvas->
translate(fMargin, (
float)(fMargin - fPos));
163 options.fCursorColor = {1, 0, 0, fBlink ? 0.0f : 1.0f};
165 options.fCursorColor = {1, 0, 0, fBlink ? 0.0f : 1.0f};
166 if (fMarkPos != Editor::TextPosition()) {
167 options.fSelectionBegin = fMarkPos;
168 options.fSelectionEnd = fTextPos;
170 #ifdef SK_EDITOR_DEBUG_OUT
172 Timer timer(
"shaping");
175 Timer timer(
"painting");
183 if (
width != fWidth) {
185 fEditor.
setWidth(fWidth - 2 * fMargin);
193 bool scroll(
int delta) {
194 int maxPos = std::max(0, fEditor.
getHeight() + 2 * fMargin - fHeight / 2);
195 int newpos = std::max(0, std::min(fPos + delta, maxPos));
196 if (newpos != fPos) {
203 void inval() {
if (fParent) { fParent->
inval(); } }
219 return this->move(fEditor.
getPosition({x - fMargin, y + fPos - fMargin}), shiftOrDrag);
226 modi &=
~skui::ModifierKey::kFirstPress;
230 if (((
unsigned)c < 0x7F && (
unsigned)c >= 0x20) || c ==
'\n') {
232 fEditor.
insert(fTextPos, &ch, 1);
233 #ifdef SK_EDITOR_DEBUG_OUT
234 SkDebugf(
"insert: %X'%c'\n", (
unsigned)c, ch);
236 return this->moveCursor(Editor::Movement::kRight);
241 if (
Any(modi & kCommandOrControl) && !
Any(modi & ~kCommandOrControl)) {
244 for (StringView str : fEditor.
text()) {
245 SkDebugf(
">> '%.*s'\n", (
int)str.size, str.data);
252 for (
size_t i = 0; i <
count; ++i) {
257 out.write(str.data, str.size);
262 if (fMarkPos != Editor::TextPosition()) {
263 fClipboard.resize(fEditor.
copy(fMarkPos, fTextPos,
nullptr));
264 fEditor.
copy(fMarkPos, fTextPos, fClipboard.data());
269 if (fMarkPos != Editor::TextPosition()) {
270 fClipboard.resize(fEditor.
copy(fMarkPos, fTextPos,
nullptr));
271 fEditor.
copy(fMarkPos, fTextPos, fClipboard.data());
272 (void)this->move(fEditor.
remove(fMarkPos, fTextPos),
false);
278 if (fClipboard.size()) {
279 fEditor.
insert(fTextPos, fClipboard.data(), fClipboard.size());
285 fTypefaceIndex = (fTypefaceIndex + 1) % kTypefaceCount;
290 fFontSize = fFontSize + 1;
296 fFontSize = fFontSize - 1;
301 #ifdef SK_EDITOR_DEBUG_OUT
302 debug_on_char(c, modifiers);
307 bool moveCursor(Editor::Movement m,
bool shift =
false) {
308 return this->move(fEditor.
move(m, fTextPos), shift);
311 bool move(Editor::TextPosition
pos,
bool shift) {
312 if (
pos == fTextPos ||
pos == Editor::TextPosition()) {
314 fMarkPos = Editor::TextPosition();
318 if (shift != fShiftDown) {
319 fMarkPos = shift ? fTextPos : Editor::TextPosition();
326 if (fPos < cursor.
bottom() - fHeight + 2 * fMargin) {
327 fPos = cursor.
bottom() - fHeight + 2 * fMargin;
328 }
else if (cursor.
top() < fPos) {
347 if (!
Any(ctrlAltCmd)) {
350 case skui::Key::kPageDown:
351 return this->scroll(fHeight * 4 / 5);
352 case skui::Key::kPageUp:
353 return this->scroll(-fHeight * 4 / 5);
354 case skui::Key::kLeft:
355 case skui::Key::kRight:
357 case skui::Key::kDown:
358 case skui::Key::kHome:
359 case skui::Key::kEnd:
361 case skui::Key::kDelete:
362 if (fMarkPos != Editor::TextPosition()) {
363 (void)this->move(fEditor.
remove(fMarkPos, fTextPos),
false);
365 auto pos = fEditor.
move(Editor::Movement::kRight, fTextPos);
366 (void)this->move(fEditor.
remove(fTextPos,
pos),
false);
370 case skui::Key::kBack:
371 if (fMarkPos != Editor::TextPosition()) {
372 (void)this->move(fEditor.
remove(fMarkPos, fTextPos),
false);
374 auto pos = fEditor.
move(Editor::Movement::kLeft, fTextPos);
375 (void)this->move(fEditor.
remove(fTextPos,
pos),
false);
380 return this->
onChar(
'\n', modifiers);
387 case skui::Key::kLeft:
388 return this->moveCursor(Editor::Movement::kWordLeft, shift);
389 case skui::Key::kRight:
390 return this->moveCursor(Editor::Movement::kWordRight, shift);
395 #ifdef SK_EDITOR_DEBUG_OUT
396 debug_on_key(
key,
state, modifiers);
413 std::unique_ptr<sk_app::Window> fWindow;
415 double fNextTime = -DBL_MAX;
417 EditorApplication(std::unique_ptr<sk_app::Window> win) : fWindow(
std::move(win)) {}
419 bool init(
const char* path) {
420 fWindow->attach(kBackendType);
422 fLayer.loadFile(path);
425 fWindow->pushLayer(&fLayer);
427 fLayer.onResize(fWindow->width(), fWindow->height());
428 fLayer.fEditor.paint(
nullptr, Editor::PaintOpts());
433 ~EditorApplication()
override { fWindow->detach(); }
437 if (now >= fNextTime) {
438 constexpr double kHalfPeriodNanoSeconds = 0.5 * 1e9;
439 fNextTime = now + kHalfPeriodNanoSeconds;
440 fLayer.fBlink = !fLayer.fBlink;
450 SK_ABORT(
"CreateNativeWindow failed.");
452 std::unique_ptr<EditorApplication>
app(
new EditorApplication(std::move(win)));
453 (void)
app->init(argc > 1 ? argv[1] : nullptr);
454 return app.release();
#define SK_ABORT(message,...)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SK_API sk_sp< SkFontMgr > SkFontMgr_New_FontConfig(FcConfig *fc)
SK_API sk_sp< SkFontMgr > SkFontMgr_New_CoreText(CTFontCollectionRef)
SK_API SkString static SkString SkStringPrintf()
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void translate(SkScalar dx, SkScalar dy)
static sk_sp< SkData > MakeFromFileName(const char path[])
SkScalar getSpacing() const
void paint(SkCanvas *canvas, PaintOpts)
SkRect getLocation(TextPosition)
void setFont(SkFont font)
StringView line(size_t i) const
size_t copy(TextPosition pos1, TextPosition pos2, char *dst=nullptr) const
TextPosition move(Editor::Movement move, Editor::TextPosition pos) const
TextPosition insert(TextPosition, const char *utf8Text, size_t byteLen)
TextPosition getPosition(SkIPoint)
TextPosition remove(TextPosition, TextPosition)
const SkFont & font() const
const char * c_str() const
static Application * Create(int argc, char **argv, void *platformData)
virtual bool onChar(SkUnichar c, skui::ModifierKey)
virtual bool onMouseWheel(float delta, int x, int y, skui::ModifierKey)
virtual bool onKey(skui::Key, skui::InputState, skui::ModifierKey)
virtual void onAttach(Window *window)
virtual void onResize(int width, int height)
virtual bool onMouse(int x, int y, skui::InputState, skui::ModifierKey)
static Window * CreateNativeWindow(void *platformData)
static Editor::Movement convert(skui::Key key)
sk_sp< SkFontMgr > fontMgr
T __attribute__((ext_vector_type(N))) V
Span< const char > StringView
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
std::enable_if_t< sknonstd::is_bitmask_enum< E >::value, bool > constexpr Any(E e)
constexpr int32_t top() const
constexpr int32_t bottom() const
void roundOut(SkIRect *dst) const