Fix some inconsistencies in object visibility/selectability tests.
[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 #include <math.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/stat.h>
34 #include <limits.h>
35
36
37 #include "BLI_utildefines.h"
38
39 #include "DNA_space_types.h"
40 #include "DNA_screen_types.h"
41
42 // #include "BKE_suggestions.h"
43 #include "BKE_report.h"
44
45 #include "BIF_gl.h"
46
47
48 #include "UI_resources.h"
49 #include "UI_interface.h"
50 #include "UI_view2d.h"
51
52 #include "info_intern.h"
53 #include "textview.h"
54 #include "GPU_framebuffer.h"
55
56 /* complicates things a bit, so leaving in old simple code */
57 #define USE_INFO_NEWLINE
58
59 static void info_report_color(unsigned char *fg, unsigned char *bg, Report *report, const short do_tint)
60 {
61         int bg_id = TH_BACK, fg_id = TH_TEXT;
62         int shade = do_tint ? 0 : -6;
63
64         if (report->flag & SELECT) {
65                 bg_id = TH_INFO_SELECTED;
66                 fg_id = TH_INFO_SELECTED_TEXT;
67         }
68         else if (report->type & RPT_ERROR_ALL) {
69                 bg_id = TH_INFO_ERROR;
70                 fg_id = TH_INFO_ERROR_TEXT;
71         }
72         else if (report->type & RPT_WARNING_ALL) {
73                 bg_id = TH_INFO_WARNING;
74                 fg_id = TH_INFO_WARNING_TEXT;
75         }
76         else if (report->type & RPT_INFO_ALL) {
77                 bg_id = TH_INFO_INFO;
78                 fg_id = TH_INFO_INFO_TEXT;
79         }
80         else if (report->type & RPT_DEBUG_ALL) {
81                 bg_id = TH_INFO_DEBUG;
82                 fg_id = TH_INFO_DEBUG_TEXT;
83         }
84         else {
85                 bg_id = TH_BACK;
86                 fg_id = TH_TEXT;
87         }
88
89         UI_GetThemeColorShade3ubv(bg_id, shade, bg);
90         UI_GetThemeColor3ubv(fg_id, fg);
91 }
92
93 /* reports! */
94 #ifdef USE_INFO_NEWLINE
95 static void report_textview_init__internal(TextViewContext *tvc)
96 {
97         Report *report = (Report *)tvc->iter;
98         const char *str = report->message;
99         const char *next_str = strchr(str + tvc->iter_char, '\n');
100
101         if (next_str) {
102                 tvc->iter_char_next = (int)(next_str - str);
103         }
104         else {
105                 tvc->iter_char_next = report->len;
106         }
107 }
108
109 static int report_textview_skip__internal(TextViewContext *tvc)
110 {
111         SpaceInfo *sinfo = (SpaceInfo *)tvc->arg1;
112         const int report_mask = info_report_mask(sinfo);
113         while (tvc->iter && (((Report *)tvc->iter)->type & report_mask) == 0) {
114                 tvc->iter = (void *)((Link *)tvc->iter)->prev;
115         }
116         return (tvc->iter != NULL);
117 }
118
119 #endif // USE_INFO_NEWLINE
120
121 static int report_textview_begin(TextViewContext *tvc)
122 {
123         // SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
124         ReportList *reports = (ReportList *)tvc->arg2;
125
126         tvc->lheight = 14 * UI_DPI_FAC; //sc->lheight;
127         tvc->sel_start = 0;
128         tvc->sel_end = 0;
129
130         /* iterator */
131         tvc->iter = reports->list.last;
132
133         UI_ThemeClearColor(TH_BACK);
134         GPU_clear(GPU_COLOR_BIT);
135
136 #ifdef USE_INFO_NEWLINE
137         tvc->iter_tmp = 0;
138         if (tvc->iter && report_textview_skip__internal(tvc)) {
139                 /* init the newline iterator */
140                 tvc->iter_char = 0;
141                 report_textview_init__internal(tvc);
142
143                 return true;
144         }
145         else {
146                 return false;
147         }
148 #else
149         return (tvc->iter != NULL);
150 #endif
151 }
152
153 static void report_textview_end(TextViewContext *UNUSED(tvc))
154 {
155         /* pass */
156 }
157
158 #ifdef USE_INFO_NEWLINE
159 static int report_textview_step(TextViewContext *tvc)
160 {
161         /* simple case, but no newline support */
162         Report *report = (Report *)tvc->iter;
163
164         if (report->len <= tvc->iter_char_next) {
165                 tvc->iter = (void *)((Link *)tvc->iter)->prev;
166                 if (tvc->iter && report_textview_skip__internal(tvc)) {
167                         tvc->iter_tmp++;
168
169                         tvc->iter_char = 0; /* reset start */
170                         report_textview_init__internal(tvc);
171
172                         return true;
173                 }
174                 else {
175                         return false;
176                 }
177         }
178         else {
179                 /* step to the next newline */
180                 tvc->iter_char = tvc->iter_char_next + 1;
181                 report_textview_init__internal(tvc);
182
183                 return true;
184         }
185 }
186
187 static int report_textview_line_get(struct TextViewContext *tvc, const char **line, int *len)
188 {
189         Report *report = (Report *)tvc->iter;
190         *line = report->message + tvc->iter_char;
191         *len = tvc->iter_char_next - tvc->iter_char;
192         return 1;
193 }
194
195 static int report_textview_line_color(struct TextViewContext *tvc, unsigned char fg[3], unsigned char bg[3])
196 {
197         Report *report = (Report *)tvc->iter;
198         info_report_color(fg, bg, report, tvc->iter_tmp % 2);
199         return TVC_LINE_FG | TVC_LINE_BG;
200 }
201
202
203 #else // USE_INFO_NEWLINE
204
205 static int report_textview_step(TextViewContext *tvc)
206 {
207         SpaceInfo *sinfo = (SpaceInfo *)tvc->arg1;
208         const int report_mask = info_report_mask(sinfo);
209         do {
210                 tvc->iter = (void *)((Link *)tvc->iter)->prev;
211         } while (tvc->iter && (((Report *)tvc->iter)->type & report_mask) == 0);
212
213         return (tvc->iter != NULL);
214 }
215
216 static int report_textview_line_get(struct TextViewContext *tvc, const char **line, int *len)
217 {
218         Report *report = (Report *)tvc->iter;
219         *line = report->message;
220         *len = report->len;
221
222         return 1;
223 }
224
225 static int report_textview_line_color(struct TextViewContext *tvc, unsigned char fg[3], unsigned char bg[3])
226 {
227         Report *report = (Report *)tvc->iter;
228         info_report_color(fg, bg, report, tvc->iter_tmp % 2);
229         return TVC_LINE_FG | TVC_LINE_BG;
230 }
231
232 #endif // USE_INFO_NEWLINE
233
234 #undef USE_INFO_NEWLINE
235
236 static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports,
237                                         int draw, int mval[2], void **mouse_pick, int *pos_pick)
238 {
239         int ret = 0;
240
241         View2D *v2d = &ar->v2d;
242
243         TextViewContext tvc = {0};
244         tvc.begin = report_textview_begin;
245         tvc.end = report_textview_end;
246
247         tvc.step = report_textview_step;
248         tvc.line_get = report_textview_line_get;
249         tvc.line_color = report_textview_line_color;
250         tvc.const_colors = NULL;
251
252         tvc.arg1 = sinfo;
253         tvc.arg2 = reports;
254
255         /* view */
256         tvc.sel_start = 0;
257         tvc.sel_end = 0;
258         tvc.lheight = 14 * UI_DPI_FAC; //sc->lheight;
259         tvc.ymin = v2d->cur.ymin;
260         tvc.ymax = v2d->cur.ymax;
261         tvc.winx = ar->winx - V2D_SCROLL_WIDTH;
262
263         ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
264
265         return ret;
266 }
267
268 void *info_text_pick(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports, int mouse_y)
269 {
270         void *mouse_pick = NULL;
271         int mval[2];
272
273         mval[0] = 0;
274         mval[1] = mouse_y;
275
276         info_textview_main__internal(sinfo, ar, reports, 0, mval, &mouse_pick, NULL);
277         return (void *)mouse_pick;
278 }
279
280
281 int info_textview_height(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports)
282 {
283         int mval[2] = {INT_MAX, INT_MAX};
284         return info_textview_main__internal(sinfo, ar, reports, 0,  mval, NULL, NULL);
285 }
286
287 void info_textview_main(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports)
288 {
289         int mval[2] = {INT_MAX, INT_MAX};
290         info_textview_main__internal(sinfo, ar, reports, 1,  mval, NULL, NULL);
291 }