style cleanup: follow style guide for formatting of if/for/while loops, and else...
[blender.git] / source / blender / editors / space_console / console_draw.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/editors/space_console/console_draw.c
24  *  \ingroup spconsole
25  */
26
27
28 #include <math.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/stat.h>
32 #include <limits.h>
33
34 #include "BLF_api.h"
35
36 #include "BLI_blenlib.h"
37 #include "BLI_utildefines.h"
38
39 #include "DNA_space_types.h"
40 #include "DNA_screen_types.h"
41
42 #include "BKE_report.h"
43
44
45 #include "MEM_guardedalloc.h"
46
47 #include "BIF_gl.h"
48 #include "BIF_glutil.h"
49
50 #include "ED_datafiles.h"
51 #include "ED_types.h"
52
53 #include "UI_resources.h"
54
55 #include "console_intern.h"
56
57
58 #include "../space_info/textview.h"
59
60 static void console_line_color(unsigned char fg[3], int type)
61 {
62         switch(type) {
63         case CONSOLE_LINE_OUTPUT:
64                 UI_GetThemeColor3ubv(TH_CONSOLE_OUTPUT, fg);
65                 break;
66         case CONSOLE_LINE_INPUT:
67                 UI_GetThemeColor3ubv(TH_CONSOLE_INPUT, fg);
68                 break;
69         case CONSOLE_LINE_INFO:
70                 UI_GetThemeColor3ubv(TH_CONSOLE_INFO, fg);
71                 break;
72         case CONSOLE_LINE_ERROR:
73                 UI_GetThemeColor3ubv(TH_CONSOLE_ERROR, fg);
74                 break;
75         }
76 }
77
78 typedef struct ConsoleDrawContext {
79         int cwidth;
80         int lheight;
81         int console_width;
82         int winx;
83         int ymin, ymax;
84 #if 0 /* used by textview, may use later */
85         int *xy; // [2]
86         int *sel; // [2]
87         int *pos_pick; // bottom of view == 0, top of file == combine chars, end of line is lower then start. 
88         int *mval; // [2]
89         int draw;
90 #endif
91 } ConsoleDrawContext;
92
93 void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy)
94 {
95         /* fake the edit line being in the scroll buffer */
96         ConsoleLine *cl= sc->history.last;
97         cl_dummy->type= CONSOLE_LINE_INPUT;
98         cl_dummy->len= cl_dummy->len_alloc= strlen(sc->prompt) + cl->len;
99         cl_dummy->len_alloc= cl_dummy->len + 1;
100         cl_dummy->line= MEM_mallocN(cl_dummy->len_alloc, "cl_dummy");
101         memcpy(cl_dummy->line, sc->prompt, (cl_dummy->len_alloc - cl->len));
102         memcpy(cl_dummy->line + ((cl_dummy->len_alloc - cl->len)) - 1, cl->line, cl->len + 1);
103         BLI_addtail(&sc->scrollback, cl_dummy);
104 }
105 void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy) 
106 {
107         MEM_freeN(cl_dummy->line);
108         BLI_remlink(&sc->scrollback, cl_dummy);
109 }
110
111 #define CONSOLE_DRAW_MARGIN 4
112 #define CONSOLE_DRAW_SCROLL 16
113
114
115
116 /* console textview callbacks */
117 static int console_textview_begin(TextViewContext *tvc)
118 {
119         SpaceConsole *sc= (SpaceConsole *)tvc->arg1;
120         tvc->lheight= sc->lheight;
121         tvc->sel_start= sc->sel_start;
122         tvc->sel_end= sc->sel_end;
123         
124         /* iterator */
125         tvc->iter= sc->scrollback.last;
126         
127         return (tvc->iter != NULL);
128 }
129
130 static void console_textview_end(TextViewContext *tvc)
131 {
132         SpaceConsole *sc= (SpaceConsole *)tvc->arg1;
133         (void)sc;
134         
135 }
136
137 static int console_textview_step(TextViewContext *tvc)
138 {
139         return ((tvc->iter= (void *)((Link *)tvc->iter)->prev) != NULL);
140 }
141
142 static int console_textview_line_get(struct TextViewContext *tvc, const char **line, int *len)
143 {
144         ConsoleLine *cl= (ConsoleLine *)tvc->iter;
145         *line= cl->line;
146         *len= cl->len;
147
148         return 1;
149 }
150
151 static int console_textview_line_color(struct TextViewContext *tvc, unsigned char fg[3], unsigned char UNUSED(bg[3]))
152 {
153         ConsoleLine *cl_iter= (ConsoleLine *)tvc->iter;
154
155         /* annoying hack, to draw the prompt */
156         if (tvc->iter_index == 0) {
157                 const SpaceConsole *sc= (SpaceConsole *)tvc->arg1;
158                 const ConsoleLine *cl= (ConsoleLine *)sc->history.last;
159                 const int prompt_len= strlen(sc->prompt);
160                 const int cursor_loc= cl->cursor + prompt_len;
161                 int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN};
162                 int pen[2];
163                 xy[1] += tvc->lheight/6;
164
165                 /* account for wrapping */
166                 if (cl->len < tvc->console_width) {
167                         /* simple case, no wrapping */
168                         pen[0]= tvc->cwidth * cursor_loc;
169                         pen[1]= -2;
170                 }
171                 else {
172                         /* wrap */
173                         pen[0]= tvc->cwidth * (cursor_loc % tvc->console_width);
174                         pen[1]= -2 + (((cl->len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight);
175                 }
176
177                 /* cursor */
178                 UI_GetThemeColor3ubv(TH_CONSOLE_CURSOR, fg);
179                 glColor3ubv(fg);
180
181                 glRecti(        (xy[0] + pen[0]) - 1,
182                                         (xy[1] + pen[1]),
183                                         (xy[0] + pen[0]) + 1,
184                                         (xy[1] + pen[1] + tvc->lheight)
185                 );
186         }
187
188         console_line_color(fg, cl_iter->type);
189
190         return TVC_LINE_FG;
191 }
192
193
194 static int console_textview_main__internal(struct SpaceConsole *sc, struct ARegion *ar, int draw, int mval[2], void **mouse_pick, int *pos_pick)
195 {
196         ConsoleLine cl_dummy= {NULL};
197         int ret= 0;
198         
199         View2D *v2d= &ar->v2d;
200
201         TextViewContext tvc= {0};
202
203         tvc.begin= console_textview_begin;
204         tvc.end= console_textview_end;
205
206         tvc.step= console_textview_step;
207         tvc.line_get= console_textview_line_get;
208         tvc.line_color= console_textview_line_color;
209
210         tvc.arg1= sc;
211         tvc.arg2= NULL;
212
213         /* view */
214         tvc.sel_start= sc->sel_start;
215         tvc.sel_end= sc->sel_end;
216         tvc.lheight= sc->lheight;
217         tvc.ymin = v2d->cur.ymin;
218         tvc.ymax = v2d->cur.ymax;
219         tvc.winx= ar->winx;
220
221         console_scrollback_prompt_begin(sc, &cl_dummy);
222         ret= textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
223         console_scrollback_prompt_end(sc, &cl_dummy);
224
225         return ret;
226 }
227
228
229 void console_textview_main(struct SpaceConsole *sc, struct ARegion *ar)
230 {
231         int mval[2] = {INT_MAX, INT_MAX};
232         console_textview_main__internal(sc, ar, 1,  mval, NULL, NULL);
233 }
234
235 int console_textview_height(struct SpaceConsole *sc, struct ARegion *ar)
236 {
237         int mval[2] = {INT_MAX, INT_MAX};
238         return console_textview_main__internal(sc, ar, 0,  mval, NULL, NULL);
239 }
240
241 int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, int mval[2])
242 {
243         int pos_pick= 0;
244         void *mouse_pick= NULL;
245         int mval_clamp[2];
246
247         mval_clamp[0]= CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx-(CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN));
248         mval_clamp[1]= CLAMPIS(mval[1], CONSOLE_DRAW_MARGIN, ar->winy-CONSOLE_DRAW_MARGIN);
249
250         console_textview_main__internal(sc, ar, 0, mval_clamp, &mouse_pick, &pos_pick);
251         return pos_pick;
252 }