]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/wxStyledTextCtrl_2.py
added comments to the makefile; added WX_CONFIG var to be able to use a different...
[wxWidgets.git] / wxPython / demo / wxStyledTextCtrl_2.py
CommitLineData
f6bcfd97
BP
1
2from wxPython.wx import *
3from wxPython.stc import *
1fded56b 4import images
f6bcfd97
BP
5import keyword
6
7#----------------------------------------------------------------------
8
9demoText = """\
10## This version of the editor has been set up to edit Python source
11## code. Here is a copy of wxPython/demo/Main.py to play with.
12
13
14"""
edf2f43e 15
f6bcfd97
BP
16#----------------------------------------------------------------------
17
18
19if wxPlatform == '__WXMSW__':
20 faces = { 'times': 'Times New Roman',
21 'mono' : 'Courier New',
22 'helv' : 'Arial',
23 'other': 'Comic Sans MS',
9968ba85
RD
24 'size' : 10,
25 'size2': 8,
f6bcfd97
BP
26 }
27else:
28 faces = { 'times': 'Times',
29 'mono' : 'Courier',
30 'helv' : 'Helvetica',
31 'other': 'new century schoolbook',
fc5d3e42
RD
32 'size' : 12,
33 'size2': 10,
f6bcfd97
BP
34 }
35
36
37#----------------------------------------------------------------------
38
39class PythonSTC(wxStyledTextCtrl):
118f4724
RD
40
41 fold_symbols = 2
42
f6bcfd97 43 def __init__(self, parent, ID):
fe953afb
RD
44 wxStyledTextCtrl.__init__(self, parent, ID,
45 style = wxNO_FULL_REPAINT_ON_RESIZE)
f6bcfd97 46
3c2ec1b8
RD
47 self.CmdKeyAssign(ord('B'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMIN)
48 self.CmdKeyAssign(ord('N'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT)
49
f6bcfd97 50 self.SetLexer(wxSTC_LEX_PYTHON)
1e4a197e 51 self.SetKeyWords(0, " ".join(keyword.kwlist))
f6bcfd97
BP
52
53 self.SetProperty("fold", "1")
54 self.SetProperty("tab.timmy.whinge.level", "1")
55 self.SetMargins(0,0)
56
1e4a197e
RD
57 self.SetViewWhiteSpace(False)
58 #self.SetBufferedDraw(False)
1fded56b 59 #self.SetViewEOL(True)
f6bcfd97
BP
60
61 self.SetEdgeMode(wxSTC_EDGE_BACKGROUND)
62 self.SetEdgeColumn(78)
63
64 # Setup a margin to hold fold markers
65 #self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
66 self.SetMarginType(2, wxSTC_MARGIN_SYMBOL)
67 self.SetMarginMask(2, wxSTC_MASK_FOLDERS)
1e4a197e 68 self.SetMarginSensitive(2, True)
1a2fb4cd
RD
69 self.SetMarginWidth(2, 12)
70
118f4724
RD
71
72 if self.fold_symbols == 0:
73 # Arrow pointing right for contracted folders, arrow pointing down for expanded
74 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_ARROWDOWN, "black", "black");
75 self.MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_ARROW, "black", "black");
76 self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY, "black", "black");
77 self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY, "black", "black");
78 self.MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_EMPTY, "white", "black");
79 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_EMPTY, "white", "black");
80 self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY, "white", "black");
81
82 elif self.fold_symbols == 1:
83 # Plus for contracted folders, minus for expanded
84 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_MINUS, "white", "black");
85 self.MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_PLUS, "white", "black");
86 self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY, "white", "black");
87 self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY, "white", "black");
88 self.MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_EMPTY, "white", "black");
89 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_EMPTY, "white", "black");
90 self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY, "white", "black");
91
92 elif self.fold_symbols == 2:
93 # Like a flattened tree control using circular headers and curved joins
94 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_CIRCLEMINUS, "white", "#404040");
95 self.MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_CIRCLEPLUS, "white", "#404040");
96 self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE, "white", "#404040");
97 self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNERCURVE, "white", "#404040");
98 self.MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040");
99 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040");
100 self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNERCURVE, "white", "#404040");
101
102 elif self.fold_symbols == 3:
103 # Like a flattened tree control using square headers
104 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS, "white", "#808080")
105 self.MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS, "white", "#808080")
106 self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE, "white", "#808080")
107 self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER, "white", "#808080")
108 self.MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUSCONNECTED, "white", "#808080")
109 self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUSCONNECTED, "white", "#808080")
110 self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER, "white", "#808080")
f6bcfd97
BP
111
112
113 EVT_STC_UPDATEUI(self, ID, self.OnUpdateUI)
114 EVT_STC_MARGINCLICK(self, ID, self.OnMarginClick)
1fded56b 115 EVT_KEY_DOWN(self, self.OnKeyPressed)
f6bcfd97
BP
116
117
118 # Make some styles, The lexer defines what each style is used for, we
119 # just have to define what each style looks like. This set is adapted from
120 # Scintilla sample property files.
121
f6bcfd97
BP
122 # Global default styles for all languages
123 self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
118f4724
RD
124 self.StyleClearAll() # Reset all to be like the default
125
f6bcfd97
BP
126 self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
127 self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
128 self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
129 self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
130
131 # Python styles
8b9a4190
RD
132 # Default
133 self.StyleSetSpec(wxSTC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
134 # Comments
b166c703 135 self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
f6bcfd97 136 # Number
b166c703 137 self.StyleSetSpec(wxSTC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
f6bcfd97 138 # String
1fded56b 139 self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
f6bcfd97 140 # Single quoted string
1fded56b 141 self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
f6bcfd97 142 # Keyword
b166c703 143 self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
f6bcfd97 144 # Triple quotes
b166c703 145 self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
f6bcfd97 146 # Triple double quotes
b166c703 147 self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
f6bcfd97 148 # Class name definition
b166c703 149 self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
f6bcfd97 150 # Function or method name definition
b166c703 151 self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
f6bcfd97 152 # Operators
b166c703 153 self.StyleSetSpec(wxSTC_P_OPERATOR, "bold,size:%(size)d" % faces)
f6bcfd97 154 # Identifiers
8b9a4190 155 self.StyleSetSpec(wxSTC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
f6bcfd97 156 # Comment-blocks
b166c703 157 self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
f6bcfd97 158 # End of line where string is not closed
c4c2f218 159 self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
f6bcfd97 160
f6bcfd97
BP
161 self.SetCaretForeground("BLUE")
162
1fded56b
RD
163
164 # register some images for use in the AutoComplete box.
165 self.RegisterImage(1, images.getSmilesBitmap())
166 self.RegisterImage(2, images.getFile1Bitmap())
3628e088 167 self.RegisterImage(3, images.getCopy2Bitmap())
1fded56b
RD
168
169
f6bcfd97
BP
170
171
172 def OnKeyPressed(self, event):
68bc8549
RD
173 if self.CallTipActive():
174 self.CallTipCancel()
f6bcfd97
BP
175 key = event.KeyCode()
176 if key == 32 and event.ControlDown():
177 pos = self.GetCurrentPos()
178 # Tips
179 if event.ShiftDown():
180 self.CallTipSetBackground("yellow")
1fded56b
RD
181 self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
182 'show some suff, maybe parameters..\n\n'
183 'fubar(param1, param2)')
f6bcfd97
BP
184 # Code completion
185 else:
c368d904
RD
186 #lst = []
187 #for x in range(50000):
188 # lst.append('%05d' % x)
1e4a197e 189 #st = " ".join(lst)
c368d904
RD
190 #print len(st)
191 #self.AutoCompShow(0, st)
8082483b
RD
192
193 kw = keyword.kwlist[:]
1fded56b
RD
194 kw.append("zzzzzz?2")
195 kw.append("aaaaa?2")
196 kw.append("__init__?3")
197 kw.append("zzaaaaa?2")
198 kw.append("zzbaaaa?2")
8082483b 199 kw.append("this_is_a_longer_value")
1fded56b 200 #kw.append("this_is_a_much_much_much_much_much_much_much_longer_value")
8082483b 201
54a816a6 202 kw.sort() # Python sorts are case sensitive
1e4a197e 203 self.AutoCompSetIgnoreCase(False) # so this needs to match
8082483b 204
1fded56b
RD
205 # Images are specified with a appended "?type"
206 for i in range(len(kw)):
207 if kw[i] in keyword.kwlist:
208 kw[i] = kw[i] + "?1"
209
1e4a197e 210 self.AutoCompShow(0, " ".join(kw))
c368d904
RD
211 else:
212 event.Skip()
f6bcfd97
BP
213
214
215 def OnUpdateUI(self, evt):
216 # check for matching braces
217 braceAtCaret = -1
1e4a197e 218 braceOpposite = -1
f6bcfd97
BP
219 charBefore = None
220 caretPos = self.GetCurrentPos()
221 if caretPos > 0:
222 charBefore = self.GetCharAt(caretPos - 1)
223 styleBefore = self.GetStyleAt(caretPos - 1)
224
225 # check before
c368d904 226 if charBefore and chr(charBefore) in "[]{}()" and styleBefore == wxSTC_P_OPERATOR:
f6bcfd97
BP
227 braceAtCaret = caretPos - 1
228
229 # check after
230 if braceAtCaret < 0:
231 charAfter = self.GetCharAt(caretPos)
232 styleAfter = self.GetStyleAt(caretPos)
c368d904 233 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == wxSTC_P_OPERATOR:
f6bcfd97
BP
234 braceAtCaret = caretPos
235
236 if braceAtCaret >= 0:
237 braceOpposite = self.BraceMatch(braceAtCaret)
238
239 if braceAtCaret != -1 and braceOpposite == -1:
c368d904 240 self.BraceBadLight(braceAtCaret)
f6bcfd97
BP
241 else:
242 self.BraceHighlight(braceAtCaret, braceOpposite)
243 #pt = self.PointFromPosition(braceOpposite)
1e4a197e 244 #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
f6bcfd97 245 #print pt
1e4a197e 246 #self.Refresh(False)
f6bcfd97
BP
247
248
249 def OnMarginClick(self, evt):
250 # fold and unfold as needed
251 if evt.GetMargin() == 2:
252 if evt.GetShift() and evt.GetControl():
253 self.FoldAll()
254 else:
c368d904 255 lineClicked = self.LineFromPosition(evt.GetPosition())
f6bcfd97
BP
256 if self.GetFoldLevel(lineClicked) & wxSTC_FOLDLEVELHEADERFLAG:
257 if evt.GetShift():
1e4a197e
RD
258 self.SetFoldExpanded(lineClicked, True)
259 self.Expand(lineClicked, True, True, 1)
f6bcfd97
BP
260 elif evt.GetControl():
261 if self.GetFoldExpanded(lineClicked):
1e4a197e
RD
262 self.SetFoldExpanded(lineClicked, False)
263 self.Expand(lineClicked, False, True, 0)
f6bcfd97 264 else:
1e4a197e
RD
265 self.SetFoldExpanded(lineClicked, True)
266 self.Expand(lineClicked, True, True, 100)
f6bcfd97
BP
267 else:
268 self.ToggleFold(lineClicked)
269
270
271 def FoldAll(self):
272 lineCount = self.GetLineCount()
1e4a197e 273 expanding = True
f6bcfd97
BP
274
275 # find out if we are folding or unfolding
276 for lineNum in range(lineCount):
277 if self.GetFoldLevel(lineNum) & wxSTC_FOLDLEVELHEADERFLAG:
278 expanding = not self.GetFoldExpanded(lineNum)
279 break;
280
281 lineNum = 0
282 while lineNum < lineCount:
283 level = self.GetFoldLevel(lineNum)
284 if level & wxSTC_FOLDLEVELHEADERFLAG and \
285 (level & wxSTC_FOLDLEVELNUMBERMASK) == wxSTC_FOLDLEVELBASE:
286
287 if expanding:
1e4a197e
RD
288 self.SetFoldExpanded(lineNum, True)
289 lineNum = self.Expand(lineNum, True)
f6bcfd97
BP
290 lineNum = lineNum - 1
291 else:
292 lastChild = self.GetLastChild(lineNum, -1)
1e4a197e 293 self.SetFoldExpanded(lineNum, False)
f6bcfd97
BP
294 if lastChild > lineNum:
295 self.HideLines(lineNum+1, lastChild)
296
297 lineNum = lineNum + 1
298
299
300
1e4a197e 301 def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
f6bcfd97 302 lastChild = self.GetLastChild(line, level)
1e4a197e 303 line = line + 1
f6bcfd97
BP
304 while line <= lastChild:
305 if force:
306 if visLevels > 0:
307 self.ShowLines(line, line)
308 else:
309 self.HideLines(line, line)
310 else:
311 if doExpand:
312 self.ShowLines(line, line)
313
314 if level == -1:
315 level = self.GetFoldLevel(line)
316
317 if level & wxSTC_FOLDLEVELHEADERFLAG:
318 if force:
319 if visLevels > 1:
1e4a197e 320 self.SetFoldExpanded(line, True)
f6bcfd97 321 else:
1e4a197e 322 self.SetFoldExpanded(line, False)
f6bcfd97
BP
323 line = self.Expand(line, doExpand, force, visLevels-1)
324
325 else:
326 if doExpand and self.GetFoldExpanded(line):
1e4a197e 327 line = self.Expand(line, True, force, visLevels-1)
f6bcfd97 328 else:
1e4a197e 329 line = self.Expand(line, False, force, visLevels-1)
f6bcfd97
BP
330 else:
331 line = line + 1;
332
333 return line
334
335
336#----------------------------------------------------------------------
337
cf273c67
RD
338_USE_PANEL = 1
339
f6bcfd97 340def runTest(frame, nb, log):
cf273c67
RD
341 if not _USE_PANEL:
342 ed = p = PythonSTC(nb, -1)
343 else:
fe953afb 344 p = wxPanel(nb, -1, style = wxNO_FULL_REPAINT_ON_RESIZE)
cf273c67
RD
345 ed = PythonSTC(p, -1)
346 s = wxBoxSizer(wxHORIZONTAL)
347 s.Add(ed, 1, wxEXPAND)
348 p.SetSizer(s)
1e4a197e 349 p.SetAutoLayout(True)
cf273c67 350
f6bcfd97
BP
351
352 ed.SetText(demoText + open('Main.py').read())
353 ed.EmptyUndoBuffer()
83b18bab 354 ed.Colourise(0, -1)
f6bcfd97
BP
355
356 # line numbers in the margin
357 ed.SetMarginType(1, wxSTC_MARGIN_NUMBER)
358 ed.SetMarginWidth(1, 25)
359
cf273c67 360 return p
f6bcfd97
BP
361
362
363
364#----------------------------------------------------------------------
365
366
367overview = """\
368<html><body>
65ec6247 369Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a>
f6bcfd97
BP
370and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should
371be helpful.
372</body><html>
373"""
374
375
774e63ef 376if __name__ == '__main__':
8641d30c 377 import sys,os
774e63ef 378 import run
8641d30c 379 run.main(['', os.path.basename(sys.argv[0])])
f6bcfd97
BP
380
381
382
383
384
385#----------------------------------------------------------------------
386#----------------------------------------------------------------------
387