| 1 | // This file is part of SmallBASIC |
| 2 | // |
| 3 | // Copyright(C) 2001-2019 Chris Warren-Smith. |
| 4 | // |
| 5 | // This program is distributed under the terms of the GPL v2.0 or later |
| 6 | // Download the GNU Public License (GPL) from www.gnu.org |
| 7 | // |
| 8 | |
| 9 | #ifndef EDITOR_WIDGET_H |
| 10 | #define EDITOR_WIDGET_H |
| 11 | |
| 12 | #include <stdint.h> |
| 13 | #include <FL/Fl_Tree.H> |
| 14 | #include <FL/Fl_Window.H> |
| 15 | #include <FL/Fl_Widget.H> |
| 16 | #include <FL/Fl_Input.H> |
| 17 | #include <FL/Fl_Toggle_Button.H> |
| 18 | #include <FL/Fl_Button.H> |
| 19 | #include <FL/Fl_Text_Editor.H> |
| 20 | #include <FL/Fl_Choice.H> |
| 21 | #include <limits.h> |
| 22 | #include "ui/strlib.h" |
| 23 | #include "platform/fltk/TtyWidget.h" |
| 24 | #include "platform/fltk/BasicEditor.h" |
| 25 | #include "platform/fltk/utils.h" |
| 26 | |
| 27 | #ifdef CALLBACK_METHOD |
| 28 | #undef CALLBACK_METHOD |
| 29 | #endif |
| 30 | |
| 31 | struct EditorWidget; |
| 32 | EditorWidget *get_editor(); |
| 33 | |
| 34 | #define CALLBACK_METHOD(FN) \ |
| 35 | void FN(Fl_Widget*w=0, void *v=0); \ |
| 36 | static void FN ## _cb(Fl_Widget *w, void *v) { \ |
| 37 | EditorWidget *e = get_editor(); \ |
| 38 | if (e) e->FN(w, v); \ |
| 39 | } |
| 40 | |
| 41 | enum RunMessage { |
| 42 | rs_err, |
| 43 | rs_run, |
| 44 | rs_ready |
| 45 | }; |
| 46 | |
| 47 | enum StyleField { |
| 48 | st_text = 0, |
| 49 | , |
| 50 | st_strings, |
| 51 | st_keywords, |
| 52 | st_funcs, |
| 53 | st_subs, |
| 54 | st_findMatches, |
| 55 | , |
| 56 | st_numbers, |
| 57 | st_operators, |
| 58 | st_selection, |
| 59 | st_background, |
| 60 | st_lineNumbers |
| 61 | }; |
| 62 | |
| 63 | enum CommandOpt { |
| 64 | cmd_find = 0, |
| 65 | cmd_find_inc, |
| 66 | cmd_replace, |
| 67 | cmd_replace_with, |
| 68 | cmd_goto, |
| 69 | cmd_input_text, |
| 70 | }; |
| 71 | |
| 72 | struct EditorWidget : public Fl_Group, StatusBar { |
| 73 | (Fl_Widget *rect, Fl_Menu_Bar *); |
| 74 | virtual ~EditorWidget(); |
| 75 | |
| 76 | CALLBACK_METHOD(change_case); |
| 77 | CALLBACK_METHOD(command); |
| 78 | CALLBACK_METHOD(command_opt); |
| 79 | CALLBACK_METHOD(cut_text); |
| 80 | CALLBACK_METHOD(do_delete); |
| 81 | CALLBACK_METHOD(expand_word); |
| 82 | CALLBACK_METHOD(find); |
| 83 | CALLBACK_METHOD(func_list); |
| 84 | CALLBACK_METHOD(goto_line); |
| 85 | CALLBACK_METHOD(paste_text); |
| 86 | CALLBACK_METHOD(rename_word); |
| 87 | CALLBACK_METHOD(replace_next); |
| 88 | CALLBACK_METHOD(save_file); |
| 89 | CALLBACK_METHOD(scroll_lock); |
| 90 | CALLBACK_METHOD(select_all); |
| 91 | CALLBACK_METHOD(set_color); |
| 92 | CALLBACK_METHOD(show_replace); |
| 93 | CALLBACK_METHOD(undo); |
| 94 | CALLBACK_METHOD(un_select); |
| 95 | CALLBACK_METHOD(clear_console); |
| 96 | |
| 97 | static void changed_cb(int, int inserted, int deleted, int, const char *, void *v) { |
| 98 | ((EditorWidget *) v)->doChange(inserted, deleted); |
| 99 | } |
| 100 | |
| 101 | bool checkSave(bool discard); |
| 102 | void copyText(); |
| 103 | void doSaveFile(const char *newfile, bool force=false); |
| 104 | void fileChanged(bool loadfile); |
| 105 | bool focusWidget(); |
| 106 | const char *getFilename() { return _filename; } |
| 107 | int getFontSize(); |
| 108 | void getInput(char *result, int size); |
| 109 | void getRowCol(int *row, int *col); |
| 110 | char *getSelection(int *start, int *end); |
| 111 | void getSelEndRowCol(int *row, int *col); |
| 112 | void getSelStartRowCol(int *row, int *col); |
| 113 | void gotoLine(int line); |
| 114 | int handle(int e); |
| 115 | bool isDirty() { return _dirty; } |
| 116 | void loadFile(const char *newfile); |
| 117 | bool readonly(); |
| 118 | void readonly(bool is_readonly); |
| 119 | void runState(RunMessage runMessage); |
| 120 | void saveSelection(const char *path); |
| 121 | void setBreakToLine(bool b) { _gotoLineBn->value(b); } |
| 122 | void setTheme(EditTheme *theme); |
| 123 | void setFont(Fl_Font font); |
| 124 | void setFontSize(int i); |
| 125 | void setHideIde(bool b) { _hideIdeBn->value(b); if (b) setLogPrint(!b); } |
| 126 | void setIndentLevel(int level); |
| 127 | void setLogPrint(bool b) { _logPrintBn->value(b); if (b) setHideIde(!b); } |
| 128 | void setRowCol(int row, int col); |
| 129 | void setScrollLock(bool b) { _lockBn->value(b); _tty->setScrollLock(b); } |
| 130 | void showPath(); |
| 131 | void statusMsg(const char *msg); |
| 132 | void updateConfig(EditorWidget *current); |
| 133 | bool isBreakToLine() { return _gotoLineBn->value(); } |
| 134 | bool isHideIDE() { return _hideIdeBn->value(); } |
| 135 | bool isLoading() { return _loading; } |
| 136 | bool isLogPrint() { return _logPrintBn->value(); } |
| 137 | bool isScrollLock() { return _lockBn->value(); } |
| 138 | void selectAll() { _editor->_textbuf->select(0, _editor->_textbuf->length()); } |
| 139 | const char *data() { return _editor->_textbuf->text(); } |
| 140 | int dataLength() { return _editor->_textbuf->length(); } |
| 141 | int top_line() { return _editor->top_line(); } |
| 142 | Fl_Text_Editor *getEditor() { return _editor; } |
| 143 | TtyWidget *getTty() { return _tty; } |
| 144 | |
| 145 | protected: |
| 146 | void addHistory(const char *filename); |
| 147 | void createFuncList(); |
| 148 | void doChange(int inserted, int deleted); |
| 149 | void findFunc(const char *find); |
| 150 | char *getSelection(Fl_Rect *rc); |
| 151 | void getKeywords(strlib::List<String *> &keywords); |
| 152 | uint32_t getModifiedTime(); |
| 153 | void handleFileChange(); |
| 154 | void resetList(); |
| 155 | void resize(int x, int y, int w, int h); |
| 156 | void newFile(); |
| 157 | void reloadFile(); |
| 158 | int replaceAll(const char *find, const char *replace, bool restorePos, bool matchWord); |
| 159 | bool searchBackward(const char *text, int startPos, const char *find, int findLen, int *foundPos); |
| 160 | void selectRowInBrowser(int row); |
| 161 | void setCommand(CommandOpt command); |
| 162 | void setModified(bool dirty); |
| 163 | void showFindText(const char *text); |
| 164 | |
| 165 | private: |
| 166 | BasicEditor *_editor; |
| 167 | TtyWidget *_tty; |
| 168 | |
| 169 | char _filename[PATH_MAX]; |
| 170 | bool _dirty; |
| 171 | bool _loading; |
| 172 | uint32_t _modifiedTime; |
| 173 | |
| 174 | // tool-bar |
| 175 | Fl_Group *_statusBar; |
| 176 | Fl_Input *_commandText; |
| 177 | Fl_Widget *_rowStatus; |
| 178 | Fl_Widget *_colStatus; |
| 179 | Fl_Button *_runStatus; |
| 180 | Fl_Button *_modStatus; |
| 181 | Fl_Tree *_funcList; |
| 182 | bool _funcListEvent; |
| 183 | |
| 184 | Fl_Toggle_Button *_logPrintBn; |
| 185 | Fl_Toggle_Button *_lockBn; |
| 186 | Fl_Toggle_Button *_hideIdeBn; |
| 187 | Fl_Toggle_Button *_gotoLineBn; |
| 188 | |
| 189 | // same order as display items |
| 190 | CommandOpt _commandOpt; |
| 191 | Fl_Button *_commandChoice; |
| 192 | |
| 193 | strlib::String _commandBuffer; |
| 194 | |
| 195 | Fl_Menu_Bar *; |
| 196 | }; |
| 197 | |
| 198 | #endif |
| 199 | |