1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21-module(dbg_wx_code).
22
23-export([code_area/1,
24	 load_code/2, unload_code/1,
25	 add_break_to_code/3, del_break_from_code/2,
26	 find/4,
27	 goto_pos/2, current_pos/1,
28	 mark_line/3, get_no_lines/1, goto_line/2]).
29
30-include_lib("wx/include/wx.hrl").
31
32-define(stc, wxStyledTextCtrl).
33
34%% For wx-2.9 usage
35-ifndef(wxSTC_ERLANG_COMMENT_FUNCTION).
36-define(wxSTC_ERLANG_COMMENT_FUNCTION, 14).
37-define(wxSTC_ERLANG_COMMENT_MODULE, 15).
38-define(wxSTC_ERLANG_COMMENT_DOC, 16).
39-define(wxSTC_ERLANG_COMMENT_DOC_MACRO, 17).
40-define(wxSTC_ERLANG_ATOM_QUOTED, 18).
41-define(wxSTC_ERLANG_MACRO_QUOTED, 19).
42-define(wxSTC_ERLANG_RECORD_QUOTED, 20).
43-define(wxSTC_ERLANG_NODE_NAME_QUOTED, 21).
44-define(wxSTC_ERLANG_BIFS, 22).
45-define(wxSTC_ERLANG_MODULES, 23).
46-define(wxSTC_ERLANG_MODULES_ATT, 24).
47-endif.
48
49code_area(Parent) ->
50    FixedFont = wxFont:new(10, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxNORMAL,[]),
51    %%Ed = wxStyledTextCtrl:new(Parent, [{size, {700, 500}}]),
52    Ed = wxStyledTextCtrl:new(Parent),
53
54    ?stc:styleClearAll(Ed),
55    ?stc:styleSetFont(Ed, ?wxSTC_STYLE_DEFAULT, FixedFont),
56    ?stc:setLexer(Ed, ?wxSTC_LEX_ERLANG),
57    ?stc:setMarginType(Ed, 0, ?wxSTC_MARGIN_NUMBER),
58    LW = ?stc:textWidth(Ed, ?wxSTC_STYLE_LINENUMBER, "9"),
59    ?stc:setMarginWidth(Ed, 0, LW),
60
61    ?stc:setSelectionMode(Ed, ?wxSTC_SEL_LINES),
62    %%?stc:hideSelection(Ed, true),
63
64    Styles =  [{?wxSTC_ERLANG_DEFAULT,  {0,0,0}},
65	       {?wxSTC_ERLANG_COMMENT,  {160,53,35}},
66	       {?wxSTC_ERLANG_VARIABLE, {150,100,40}},
67	       {?wxSTC_ERLANG_NUMBER,   {5,5,100}},
68	       {?wxSTC_ERLANG_KEYWORD,  {130,40,172}},
69	       {?wxSTC_ERLANG_STRING,   {170,45,132}},
70	       {?wxSTC_ERLANG_OPERATOR, {30,0,0}},
71	       {?wxSTC_ERLANG_ATOM,     {0,0,0}},
72	       {?wxSTC_ERLANG_FUNCTION_NAME, {64,102,244}},
73	       {?wxSTC_ERLANG_CHARACTER,{236,155,172}},
74	       {?wxSTC_ERLANG_MACRO,    {40,144,170}},
75	       {?wxSTC_ERLANG_RECORD,   {40,100,20}},
76	       {?wxSTC_ERLANG_NODE_NAME,{0,0,0}},
77	       %% Optional 2.9 stuff
78	       {?wxSTC_ERLANG_COMMENT_FUNCTION, {160,53,35}},
79	       {?wxSTC_ERLANG_COMMENT_MODULE, {160,53,35}},
80	       {?wxSTC_ERLANG_COMMENT_DOC, {160,53,35}},
81	       {?wxSTC_ERLANG_COMMENT_DOC_MACRO, {160,53,35}},
82	       {?wxSTC_ERLANG_ATOM_QUOTED, {0,0,0}},
83	       {?wxSTC_ERLANG_MACRO_QUOTED, {40,144,170}},
84	       {?wxSTC_ERLANG_RECORD_QUOTED, {40,100,20}},
85	       {?wxSTC_ERLANG_NODE_NAME_QUOTED, {0,0,0}},
86	       {?wxSTC_ERLANG_BIFS, {130,40,172}},
87	       {?wxSTC_ERLANG_MODULES, {64,102,244}},
88	       {?wxSTC_ERLANG_MODULES_ATT, {64,102,244}}
89	      ],
90
91    SetStyle = fun({Style, Color}) ->
92		       ?stc:styleSetFont(Ed, Style, FixedFont),
93		       ?stc:styleSetForeground(Ed, Style, Color)
94	       end,
95    [SetStyle(Style) || Style <- Styles],
96    ?stc:setKeyWords(Ed, 0, keyWords()),
97
98    %% Margins Markers
99    %% Breakpoint Should be a pixmap?
100    ?stc:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, [{foreground, {170,20,20}}]),
101    ?stc:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, [{background, {200,120,120}}]),
102    %% Disabled Breakpoint
103    ?stc:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, [{foreground, {20,20,170}}]),
104    ?stc:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, [{background, {120,120,200}}]),
105
106    %% Current Line
107    ?stc:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW,  [{foreground, {20,170,20}}]),
108    ?stc:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW,  [{background, {200,255,200}}]),
109    ?stc:markerDefine(Ed, 3, ?wxSTC_MARK_BACKGROUND, [{background, {200,255,200}}]),
110
111    %% Scrolling
112    Policy = ?wxSTC_CARET_SLOP bor ?wxSTC_CARET_JUMPS bor ?wxSTC_CARET_EVEN,
113    ?stc:setYCaretPolicy(Ed, Policy, 3),
114    ?stc:setVisiblePolicy(Ed, Policy, 3),
115
116    ?stc:connect(Ed, stc_doubleclick),
117    ?stc:setReadOnly(Ed, true),
118    %% STC steals keyboard shortcuts on linux for some reason
119    ?stc:cmdKeyClearAll(Ed),
120    ?stc:cmdKeyAssign(Ed, ?wxSTC_KEY_DOWN, ?wxSTC_KEYMOD_NORM, ?wxSTC_CMD_LINEDOWN),
121    ?stc:cmdKeyAssign(Ed, ?wxSTC_KEY_UP, ?wxSTC_KEYMOD_NORM, ?wxSTC_CMD_LINEUP),
122    Ed.
123
124load_code(Ed, Code) ->
125    ?stc:setReadOnly(Ed, false),
126    ?stc:setTextRaw(Ed, Code),
127    Lines = ?stc:getLineCount(Ed),
128    Sz = trunc(math:log10(Lines))+1,
129    LW = ?stc:textWidth(Ed, ?wxSTC_STYLE_LINENUMBER, lists:duplicate(Sz, $9)),
130    %%io:format("~p ~p ~p~n", [Lines, Sz, LW]),
131    ?stc:setMarginWidth(Ed, 0, LW+5),
132    ?stc:setReadOnly(Ed, true),
133    ok.
134
135unload_code(Ed) ->
136    ?stc:setReadOnly(Ed, false),
137    ?stc:setTextRaw(Ed, <<0:8>>),
138    ?stc:setReadOnly(Ed, true),
139    ok.
140
141add_break_to_code(Ed, Line, active) ->
142    ?stc:markerDelete(Ed, Line-1, 1),
143    ?stc:markerAdd(Ed, Line-1, 0),
144    ok;
145add_break_to_code(Ed, Line, inactive) ->
146    ?stc:markerDelete(Ed, Line-1, 0),
147    ?stc:markerAdd(Ed, Line-1, 1),
148    ok.
149
150del_break_from_code(Ed,Line) ->
151    ?stc:markerDelete(Ed, Line-1, 0),
152    ?stc:markerDelete(Ed, Line-1, 1).
153
154mark_line(Ed,Prev,Line) ->
155    goto_line(Ed, Line),
156    ?stc:markerDelete(Ed, Prev-1, 2),
157    ?stc:markerAdd(Ed, Line-1, 2),
158    ?stc:markerDelete(Ed, Prev-1, 3),
159    ?stc:markerAdd(Ed, Line-1, 3).
160
161get_no_lines(Ed) ->
162    ?stc:getLineCount(Ed).
163
164goto_line(_Ed,0) -> ignore;
165goto_line(Ed,Line) ->
166    ?stc:gotoLine(Ed, Line-1).
167
168current_pos(Ed) ->
169    ?stc:getCurrentPos(Ed).
170
171goto_pos(Ed,Pos) ->
172    ?stc:gotoPos(Ed, Pos).
173
174find(Ed, Str, Case, Next) ->
175    ?stc:searchAnchor(Ed),
176    Flag =
177	if  Case -> ?wxSTC_FIND_MATCHCASE;
178	    true -> 0
179	end,
180    Res =
181	if
182	    Next -> ?stc:searchNext(Ed, Flag, Str);
183	    true -> ?stc:searchPrev(Ed, Flag, Str)
184	end,
185    case Res >= 0 of
186	true ->
187	    %% io:format("Found ~p ~n",[Res]),
188	    ?stc:scrollToLine(Ed,?stc:lineFromPosition(Ed,Res) - 3),
189	    true;
190	false ->
191	    false
192    end.
193
194keyWords() ->
195    L = ["after","begin","case","try","cond","catch","andalso","orelse",
196	 "end","fun","if","let","of","receive","when","bnot","not",
197	 "div","rem","band","and","bor","bxor","bsl","bsr","or","xor"],
198    lists:flatten([K ++ " " || K <- L] ++ [0]).
199