Holiday coding log :)
[blender.git] / source / blender / editors / space_info / info_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  * The Original Code is Copyright (C) 2010 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_info/info_draw.c
27  *  \ingroup spinfo
28  */
29
30
31
32 #include <math.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/stat.h>
36 #include <limits.h>
37
38 #include "BLF_api.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_utildefines.h"
42
43 #include "DNA_space_types.h"
44 #include "DNA_screen_types.h"
45
46 // #include "BKE_suggestions.h"
47 #include "BKE_report.h"
48
49
50 #include "MEM_guardedalloc.h"
51
52 #include "BIF_gl.h"
53 #include "BIF_glutil.h"
54
55 #include "ED_datafiles.h"
56 #include "ED_types.h"
57
58 #include "UI_resources.h"
59 #include "UI_interface.h"
60
61 #include "info_intern.h"
62 #include "../space_info/textview.h"
63
64 /* complicates things a bit, so leaving in old simple code */
65 #define USE_INFO_NEWLINE
66
67 static void info_report_color(unsigned char *fg, unsigned char *bg, Report *report, const short do_tint)
68 {
69         if (report->flag & SELECT) {
70                 fg[0] = 255; fg[1] = 255; fg[2] = 255;
71                 if (do_tint) {
72                         bg[0] = 96; bg[1] = 128; bg[2] = 255;
73                 }
74                 else {
75                         bg[0] = 90; bg[1] = 122; bg[2] = 249;
76                 }
77         }
78         else {
79                 fg[0] = 0; fg[1] = 0; fg[2] = 0;
80                 
81                 if (report->type & RPT_ERROR_ALL) {
82                         if (do_tint) { bg[0] = 220; bg[1] = 0;   bg[2] = 0;   }
83                         else         { bg[0] = 214; bg[1] = 0;   bg[2] = 0;   }
84                 }
85                 else if (report->type & RPT_WARNING_ALL) {
86                         if (do_tint) { bg[0] = 220; bg[1] = 128; bg[2] = 96;  }
87                         else         { bg[0] = 214; bg[1] = 122; bg[2] = 90;  }
88                 }
89 #if 0 // XXX: this looks like the selected color, so don't use this
90                 else if (report->type & RPT_OPERATOR_ALL) {
91                         if (do_tint) { bg[0] = 96;  bg[1] = 128; bg[2] = 255; }
92                         else         { bg[0] = 90;  bg[1] = 122; bg[2] = 249; }
93                 }
94 #endif
95                 else if (report->type & RPT_INFO_ALL) {
96                         if (do_tint) { bg[0] = 0;   bg[1] = 170; bg[2] = 0;   }
97                         else         { bg[0] = 0;   bg[1] = 164; bg[2] = 0;   }
98                 }
99                 else if (report->type & RPT_DEBUG_ALL) {
100                         if (do_tint) { bg[0] = 196; bg[1] = 196; bg[2] = 196; }
101                         else         { bg[0] = 190; bg[1] = 190; bg[2] = 190; }
102                 }
103                 else {
104                         if (do_tint) { bg[0] = 120; bg[1] = 120; bg[2] = 120; }
105                         else         { bg[0] = 114; bg[1] = 114; bg[2] = 114; }
106                 }
107         }
108 }
109
110 /* reports! */
111 #ifdef USE_INFO_NEWLINE
112 static void report_textview_init__internal(TextViewContext *tvc)
113 {
114         Report *report = (Report *)tvc->iter;
115         const char *str = report->message;
116         const char *next_str = strchr(str + tvc->iter_char, '\n');
117
118         if (next_str) {
119                 tvc->iter_char_next = (int)(next_str - str);
120         }
121         else {
122                 tvc->iter_char_next = report->len;
123         }
124 }
125
126 static int report_textview_skip__internal(TextViewContext *tvc)
127 {
128         SpaceInfo *sinfo = (SpaceInfo *)tvc->arg1;
129         const int report_mask = info_report_mask(sinfo);
130         while (tvc->iter && (((Report *)tvc->iter)->type & report_mask) == 0) {
131                 tvc->iter = (void *)((Link *)tvc->iter)->prev;
132         }
133         return (tvc->iter != NULL);
134 }
135
136 #endif // USE_INFO_NEWLINE
137
138 static int report_textview_begin(TextViewContext *tvc)
139 {
140         // SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
141         ReportList *reports = (ReportList *)tvc->arg2;
142
143         tvc->lheight = 14 * UI_DPI_FAC; //sc->lheight;
144         tvc->sel_start = 0;
145         tvc->sel_end = 0;
146
147         /* iterator */
148         tvc->iter = reports->list.last;
149
150         glClearColor(120.0 / 255.0, 120.0 / 255.0, 120.0 / 255.0, 1.0);
151         glClear(GL_COLOR_BUFFER_BIT);
152
153 #ifdef USE_INFO_NEWLINE
154         tvc->iter_tmp = 0;
155         if (tvc->iter && report_textview_skip__internal(tvc)) {
156                 /* init the newline iterator */
157                 tvc->iter_char = 0;
158                 report_textview_init__internal(tvc);
159
160                 return TRUE;
161         }
162         else {
163                 return FALSE;
164         }
165 #else
166         return (tvc->iter != NULL);
167 #endif
168 }
169
170 static void report_textview_end(TextViewContext *UNUSED(tvc))
171 {
172         /* pass */
173 }
174
175 #ifdef USE_INFO_NEWLINE
176 static int report_textview_step(TextViewContext *tvc)
177 {
178         /* simple case, but no newline support */
179         Report *report = (Report *)tvc->iter;
180
181         if (report->len <= tvc->iter_char_next) {
182                 tvc->iter = (void *)((Link *)tvc->iter)->prev;
183                 if (tvc->iter && report_textview_skip__internal(tvc)) {
184                         tvc->iter_tmp++;
185
186                         tvc->iter_char = 0; /* reset start */
187                         report_textview_init__internal(tvc);
188
189                         return TRUE;
190                 }
191                 else {
192                         return FALSE;
193                 }
194         }
195         else {
196                 /* step to the next newline */
197                 tvc->iter_char = tvc->iter_char_next + 1;
198                 report_textview_init__internal(tvc);
199
200                 return TRUE;
201         }
202 }
203
204 static int report_textview_line_get(struct TextViewContext *tvc, const char **line, int *len)
205 {
206         Report *report = (Report *)tvc->iter;
207         *line = report->message + tvc->iter_char;
208         *len = tvc->iter_char_next - tvc->iter_char;
209         return 1;
210 }
211
212 static int report_textview_line_color(struct TextViewContext *tvc, unsigned char fg[3], unsigned char bg[3])
213 {
214         Report *report = (Report *)tvc->iter;
215         info_report_color(fg, bg, report, tvc->iter_tmp % 2);
216         return TVC_LINE_FG | TVC_LINE_BG;
217 }
218
219
220 #else // USE_INFO_NEWLINE
221
222 static int report_textview_step(TextViewContext *tvc)
223 {
224         SpaceInfo *sinfo = (SpaceInfo *)tvc->arg1;
225         const int report_mask = info_report_mask(sinfo);
226         do {
227                 tvc->iter = (void *)((Link *)tvc->iter)->prev;
228         } while (tvc->iter && (((Report *)tvc->iter)->type & report_mask) == 0);
229
230         return (tvc->iter != NULL);
231 }
232
233 static int report_textview_line_get(struct TextViewContext *tvc, const char **line, int *len)
234 {
235         Report *report = (Report *)tvc->iter;
236         *line = report->message;
237         *len = report->len;
238
239         return 1;
240 }
241
242 static int report_textview_line_color(struct TextViewContext *tvc, unsigned char fg[3], unsigned char bg[3])
243 {
244         Report *report = (Report *)tvc->iter;
245         info_report_color(fg, bg, report, tvc->iter_tmp % 2);
246         return TVC_LINE_FG | TVC_LINE_BG;
247 }
248
249 #endif // USE_INFO_NEWLINE
250
251 #undef USE_INFO_NEWLINE
252
253 static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports, int draw, int mval[2], void **mouse_pick, int *pos_pick)
254 {
255         int ret = 0;
256         
257         View2D *v2d = &ar->v2d;
258
259         TextViewContext tvc = {0};
260         tvc.begin = report_textview_begin;
261         tvc.end = report_textview_end;
262
263         tvc.step = report_textview_step;
264         tvc.line_get = report_textview_line_get;
265         tvc.line_color = report_textview_line_color;
266
267         tvc.arg1 = sinfo;
268         tvc.arg2 = reports;
269
270         /* view */
271         tvc.sel_start = 0;
272         tvc.sel_end = 0;
273         tvc.lheight = 14 * UI_DPI_FAC; //sc->lheight;
274         tvc.ymin = v2d->cur.ymin;
275         tvc.ymax = v2d->cur.ymax;
276         tvc.winx = ar->winx;
277
278         ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
279         
280         return ret;
281 }
282
283 void *info_text_pick(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports, int mouse_y)
284 {
285         void *mouse_pick = NULL;
286         int mval[2];
287
288         mval[0] = 0;
289         mval[1] = mouse_y;
290
291         info_textview_main__internal(sinfo, ar, reports, 0, mval, &mouse_pick, NULL);
292         return (void *)mouse_pick;
293 }
294
295
296 int info_textview_height(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports)
297 {
298         int mval[2] = {INT_MAX, INT_MAX};
299         return info_textview_main__internal(sinfo, ar, reports, 0,  mval, NULL, NULL);
300 }
301
302 void info_textview_main(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports)
303 {
304         int mval[2] = {INT_MAX, INT_MAX};
305         info_textview_main__internal(sinfo, ar, reports, 1,  mval, NULL, NULL);
306 }