/[svn]/gigedit/trunk/src/gigedit/scripteditor.cpp
ViewVC logotype

Annotation of /gigedit/trunk/src/gigedit/scripteditor.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2887 - (hide annotations) (download)
Fri Apr 22 17:10:51 2016 UTC (7 years, 11 months ago) by schoenebeck
File size: 9067 byte(s)
* Script Editor: Some color tweaks (using now same text colors as on
  the NKSP refrence documentation website).
* Bumped version (1.0.0.svn3).

1 schoenebeck 2604 /*
2 schoenebeck 2886 Copyright (c) 2014-2016 Christian Schoenebeck
3 schoenebeck 2604
4     This file is part of "gigedit" and released under the terms of the
5     GNU General Public License version 2.
6     */
7    
8     #include "scripteditor.h"
9     #include "global.h"
10 schoenebeck 2886 #if USE_LS_SCRIPTVM
11     # include <linuxsampler/scriptvm/ScriptVM.h>
12     #endif
13 schoenebeck 2604
14 schoenebeck 2886 #if !USE_LS_SCRIPTVM
15    
16 schoenebeck 2604 static const std::string _keywords[] = {
17     "on", "end", "declare", "while", "if", "or", "and", "not", "else", "case",
18     "select", "to", "const", "polyphonic", "mod"
19     };
20     static int _keywordsSz = sizeof(_keywords) / sizeof(std::string);
21    
22     static const std::string _eventNames[] = {
23     "init", "note", "release", "controller"
24     };
25     static int _eventNamesSz = sizeof(_eventNames) / sizeof(std::string);
26    
27     static bool isKeyword(const Glib::ustring& s) {
28     for (int i = 0; i < _keywordsSz; ++i)
29     if (_keywords[i] == s) return true;
30     return false;
31     }
32    
33     static bool isEvent(const Glib::ustring& s) {
34     for (int i = 0; i < _eventNamesSz; ++i)
35     if (_eventNames[i] == s) return true;
36     return false;
37     }
38    
39 schoenebeck 2886 #endif // !USE_LS_SCRIPTVM
40    
41 schoenebeck 2604 ScriptEditor::ScriptEditor() :
42 persson 2845 m_applyButton(_("_Apply"), true),
43     m_cancelButton(_("_Cancel"), true)
44 schoenebeck 2604 {
45     m_script = NULL;
46 schoenebeck 2886 m_vm = NULL;
47 schoenebeck 2604
48     add(m_vbox);
49    
50     m_tagTable = Gtk::TextBuffer::TagTable::create();
51 schoenebeck 2886
52 schoenebeck 2604 m_keywordTag = Gtk::TextBuffer::Tag::create();
53 schoenebeck 2887 m_keywordTag->property_foreground() = "#000000"; // black
54 schoenebeck 2604 m_keywordTag->property_weight() = PANGO_WEIGHT_BOLD;
55     m_tagTable->add(m_keywordTag);
56 schoenebeck 2886
57 schoenebeck 2604 m_eventTag = Gtk::TextBuffer::Tag::create();
58 schoenebeck 2887 m_eventTag->property_foreground() = "#07c0cf"; // cyan 1
59 schoenebeck 2610 m_eventTag->property_weight() = PANGO_WEIGHT_BOLD;
60 schoenebeck 2604 m_tagTable->add(m_eventTag);
61 schoenebeck 2886
62     m_variableTag = Gtk::TextBuffer::Tag::create();
63 schoenebeck 2887 m_variableTag->property_foreground() = "#790cc4"; // magenta
64 schoenebeck 2886 m_tagTable->add(m_variableTag);
65    
66     m_functionTag = Gtk::TextBuffer::Tag::create();
67 schoenebeck 2887 m_functionTag->property_foreground() = "#1ba1dd"; // cyan 2
68 schoenebeck 2886 m_tagTable->add(m_functionTag);
69    
70     m_numberTag = Gtk::TextBuffer::Tag::create();
71 schoenebeck 2887 m_numberTag->property_foreground() = "#c4950c"; // yellow
72 schoenebeck 2886 m_tagTable->add(m_numberTag);
73    
74     m_stringTag = Gtk::TextBuffer::Tag::create();
75 schoenebeck 2887 m_stringTag->property_foreground() = "#c40c0c"; // red
76 schoenebeck 2886 m_tagTable->add(m_stringTag);
77    
78     m_commentTag = Gtk::TextBuffer::Tag::create();
79 schoenebeck 2887 m_commentTag->property_foreground() = "#9c9c9c"; // gray
80 schoenebeck 2886 m_tagTable->add(m_commentTag);
81    
82     m_preprocTag = Gtk::TextBuffer::Tag::create();
83 schoenebeck 2887 m_preprocTag->property_foreground() = "#2f8a33"; // green
84 schoenebeck 2886 m_tagTable->add(m_preprocTag);
85    
86 schoenebeck 2604 m_textBuffer = Gtk::TextBuffer::create(m_tagTable);
87     m_textView.set_buffer(m_textBuffer);
88     {
89     Pango::FontDescription fdesc;
90     fdesc.set_family("monospace");
91 schoenebeck 2664 #if defined(__APPLE__)
92     fdesc.set_size(12 * PANGO_SCALE);
93     #else
94 schoenebeck 2604 fdesc.set_size(10 * PANGO_SCALE);
95 schoenebeck 2664 #endif
96 schoenebeck 2604 #if GTKMM_MAJOR_VERSION < 3
97     m_textView.modify_font(fdesc);
98     #else
99     m_textView.override_font(fdesc);
100     #endif
101     }
102     m_scrolledWindow.add(m_textView);
103     m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
104     m_vbox.pack_start(m_scrolledWindow);
105    
106     m_buttonBox.set_layout(Gtk::BUTTONBOX_END);
107     m_buttonBox.pack_start(m_applyButton);
108     m_buttonBox.pack_start(m_cancelButton);
109     m_applyButton.set_can_default();
110     m_applyButton.set_sensitive(false);
111     m_applyButton.grab_focus();
112     m_vbox.pack_start(m_buttonBox, Gtk::PACK_SHRINK);
113    
114     m_applyButton.signal_clicked().connect(
115     sigc::mem_fun(*this, &ScriptEditor::onButtonApply)
116     );
117    
118     m_cancelButton.signal_clicked().connect(
119     sigc::mem_fun(*this, &ScriptEditor::onButtonCancel)
120     );
121    
122     m_textBuffer->signal_insert().connect(
123     sigc::mem_fun(*this, &ScriptEditor::onTextInserted)
124     );
125    
126     m_textBuffer->signal_erase().connect(
127     sigc::mem_fun(*this, &ScriptEditor::onTextErased)
128     );
129    
130     m_textBuffer->signal_modified_changed().connect(
131     sigc::mem_fun(*this, &ScriptEditor::onModifiedChanged)
132     );
133    
134     signal_hide().connect(
135     sigc::mem_fun(*this, &ScriptEditor::onWindowHide)
136     );
137    
138     show_all_children();
139    
140     resize(460,300);
141     }
142    
143     ScriptEditor::~ScriptEditor() {
144     printf("ScriptEditor destruct\n");
145 schoenebeck 2886 if (m_vm) delete m_vm;
146 schoenebeck 2604 }
147    
148     void ScriptEditor::setScript(gig::Script* script) {
149     m_script = script;
150     if (!script) {
151     set_title(_("No Script"));
152     return;
153     }
154    
155     set_title(std::string(_("Instrument Script")) + " - \"" + script->Name + "\"");
156    
157     std::string txt = script->GetScriptAsText();
158     //printf("text : '%s'\n", txt.c_str());
159     m_textBuffer->set_text(txt);
160     m_textBuffer->set_modified(false);
161     }
162    
163     void ScriptEditor::onTextInserted(const Gtk::TextBuffer::iterator& itEnd, const Glib::ustring& txt, int length) {
164 schoenebeck 2886 #if USE_LS_SCRIPTVM
165     updateSyntaxHighlightingByVM();
166     #else
167 schoenebeck 2610 //printf("inserted %d\n", length);
168 schoenebeck 2604 Gtk::TextBuffer::iterator itStart = itEnd;
169     itStart.backward_chars(length);
170    
171     Gtk::TextBuffer::iterator it = itStart;
172     it.backward_word_start();
173    
174     bool eofReached = false;
175     while (it <= itEnd) {
176     Gtk::TextBuffer::iterator itWordStart = it;
177     if (!it.forward_word_end()) {
178     eofReached = true;
179     it = itEnd;
180     }
181    
182     Glib::ustring s = m_textBuffer->get_text(itWordStart, it, false);
183 schoenebeck 2610 //printf("{%s}\n", s.c_str());
184 schoenebeck 2604 if (isKeyword(s))
185     m_textBuffer->apply_tag(m_keywordTag, itWordStart, it);
186     else if (isEvent(s)) {
187     // check if previous word is "on"
188     Gtk::TextBuffer::iterator itPreviousWordStart = itWordStart;
189     if (itPreviousWordStart.backward_word_start()) {
190     Gtk::TextBuffer::iterator itPreviousWordEnd = itPreviousWordStart;
191     itPreviousWordEnd.forward_word_end();
192     if (m_textBuffer->get_text(itPreviousWordStart, itPreviousWordEnd, false) == "on") {
193     m_textBuffer->apply_tag(m_eventTag, itWordStart, it);
194     }
195     }
196     }
197    
198     if (eofReached) break;
199    
200     while (!it.inside_word())
201     if (!it.forward_char())
202     goto EOF_REACHED;
203     }
204    
205     EOF_REACHED:
206     ;
207 schoenebeck 2886
208     #endif // USE_LS_SCRIPTVM
209 schoenebeck 2604 }
210    
211 schoenebeck 2886 #if USE_LS_SCRIPTVM
212    
213     static void applyCodeTag(Glib::RefPtr<Gtk::TextBuffer>& txtbuf, const LinuxSampler::VMSourceToken& token, Glib::RefPtr<Gtk::TextBuffer::Tag>& tag) {
214     Gtk::TextBuffer::iterator itStart =
215     txtbuf->get_iter_at_line_index(token.firstLine(), token.firstColumn());
216     Gtk::TextBuffer::iterator itEnd = itStart;
217     const int length = token.text().length();
218     itEnd.forward_chars(length);
219     txtbuf->apply_tag(tag, itStart, itEnd);
220     }
221    
222     void ScriptEditor::updateSyntaxHighlightingByVM() {
223     if (!m_vm) m_vm = new LinuxSampler::ScriptVM();
224     const std::string s = m_textBuffer->get_text();
225     std::vector<LinuxSampler::VMSourceToken> tokens = m_vm->syntaxHighlighting(s);
226    
227     m_textBuffer->remove_all_tags(m_textBuffer->begin(), m_textBuffer->end());
228    
229     for (int i = 0; i < tokens.size(); ++i) {
230     const LinuxSampler::VMSourceToken& token = tokens[i];
231    
232     if (token.isKeyword()) {
233     applyCodeTag(m_textBuffer, token, m_keywordTag);
234     } else if (token.isVariableName()) {
235     applyCodeTag(m_textBuffer, token, m_variableTag);
236     } else if (token.isIdentifier()) {
237     if (token.isEventHandlerName()) {
238     applyCodeTag(m_textBuffer, token, m_eventTag);
239     } else { // a function ...
240     applyCodeTag(m_textBuffer, token, m_functionTag);
241     }
242     } else if (token.isNumberLiteral()) {
243     applyCodeTag(m_textBuffer, token, m_numberTag);
244     } else if (token.isStringLiteral()) {
245     applyCodeTag(m_textBuffer, token, m_stringTag);
246     } else if (token.isComment()) {
247     applyCodeTag(m_textBuffer, token, m_commentTag);
248     } else if (token.isPreprocessor()) {
249     applyCodeTag(m_textBuffer, token, m_preprocTag);
250     } else if (token.isNewLine()) {
251     }
252     }
253     }
254    
255     #endif // USE_LS_SCRIPTVM
256    
257 schoenebeck 2604 void ScriptEditor::onTextErased(const Gtk::TextBuffer::iterator& itStart, const Gtk::TextBuffer::iterator& itEnd) {
258 schoenebeck 2610 //printf("erased\n");
259 schoenebeck 2886 #if USE_LS_SCRIPTVM
260     updateSyntaxHighlightingByVM();
261     #else
262 schoenebeck 2604 Gtk::TextBuffer::iterator itStart2 = itStart;
263     if (itStart2.inside_word() || itStart2.ends_word())
264     itStart2.backward_word_start();
265    
266     Gtk::TextBuffer::iterator itEnd2 = itEnd;
267     if (itEnd2.inside_word()) itEnd2.forward_word_end();
268    
269     m_textBuffer->remove_all_tags(itStart2, itEnd2);
270 schoenebeck 2886 #endif // USE_LS_SCRIPTVM
271 schoenebeck 2604 }
272    
273     void ScriptEditor::onModifiedChanged() {
274     m_applyButton.set_sensitive( m_textBuffer->get_modified() );
275     }
276    
277     void ScriptEditor::onButtonCancel() {
278     hide();
279     }
280    
281     void ScriptEditor::onButtonApply() {
282     m_script->SetScriptAsText(m_textBuffer->get_text());
283     m_textBuffer->set_modified(false);
284     }
285    
286     void ScriptEditor::onWindowHide() {
287     delete this; // this is the end, my friend
288     }

  ViewVC Help
Powered by ViewVC