Blender V5.0
console_draw.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstring>
10
11#include "BLI_listbase.h"
12#include "BLI_string_utf8.h"
13
14#include "DNA_screen_types.h"
15#include "DNA_space_types.h"
16#include "DNA_userdef_types.h"
17
18#include "MEM_guardedalloc.h"
19
20#include "GPU_immediate.hh"
21
22#include "UI_resources.hh"
23#include "UI_view2d.hh"
24
25#include "console_intern.hh"
26
28
30 uchar fg[4],
31 uchar /*bg*/[4],
32 int * /*icon*/,
33 uchar /*icon_fg*/[4],
34 uchar /*icon_bg*/[4])
35{
36 const ConsoleLine *cl_iter = static_cast<const ConsoleLine *>(tvc->iter);
37 int fg_id = TH_TEXT;
38
39 switch (cl_iter->type) {
41 fg_id = TH_CONSOLE_OUTPUT;
42 break;
44 fg_id = TH_CONSOLE_INPUT;
45 break;
47 fg_id = TH_CONSOLE_INFO;
48 break;
50 fg_id = TH_CONSOLE_ERROR;
51 break;
52 }
53
54 UI_GetThemeColor4ubv(fg_id, fg);
55 return TVC_LINE_FG;
56}
57
59{
60 /* fake the edit line being in the scroll buffer */
61 ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
62 int prompt_len = strlen(sc->prompt);
63
64 cl_dummy->type = CONSOLE_LINE_INPUT;
65 cl_dummy->len = prompt_len + cl->len;
66 cl_dummy->len_alloc = cl_dummy->len + 1;
67 cl_dummy->line = MEM_malloc_arrayN<char>(cl_dummy->len_alloc, "cl_dummy");
68 memcpy(cl_dummy->line, sc->prompt, prompt_len);
69 memcpy(cl_dummy->line + prompt_len, cl->line, cl->len + 1);
70 BLI_addtail(&sc->scrollback, cl_dummy);
71}
73{
74 MEM_freeN(cl_dummy->line);
75 BLI_remlink(&sc->scrollback, cl_dummy);
76}
77
78/* console textview callbacks */
80{
81 SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
82 tvc->sel_start = sc->sel_start;
83 tvc->sel_end = sc->sel_end;
84
85 /* iterator */
86 tvc->iter = sc->scrollback.last;
87
88 return (tvc->iter != nullptr);
89}
90
92{
93 SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
94 (void)sc;
95}
96
98{
99 return ((tvc->iter = (void *)((Link *)tvc->iter)->prev) != nullptr);
100}
101
102static void console_textview_line_get(TextViewContext *tvc, const char **r_line, int *r_len)
103{
104 const ConsoleLine *cl = static_cast<const ConsoleLine *>(tvc->iter);
105 *r_line = cl->line;
106 *r_len = cl->len;
107 // printf("'%s' %d\n", *line, cl->len);
108 BLI_assert(cl->line[cl->len] == '\0' && (cl->len == 0 || cl->line[cl->len - 1] != '\0'));
109}
110
112 const char *str, int width, int *row, int *column, const char *end)
113{
114 int col;
115 const int tab_width = 4;
116
117 for (; *str; str += BLI_str_utf8_size_safe(str)) {
118 col = UNLIKELY(*str == '\t') ? (tab_width - (*column % tab_width)) :
120
121 if (*column + col > width) {
122 (*row)++;
123 *column = 0;
124 }
125
126 if (end && str >= end) {
127 break;
128 }
129
130 *column += col;
131 }
132}
133
134static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int columns)
135{
136 int pen[2];
137 {
138 const SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
139 const ConsoleLine *cl = (ConsoleLine *)sc->history.last;
140 int offl = 0, offc = 0;
141
142 console_cursor_wrap_offset(sc->prompt, columns, &offl, &offc, nullptr);
143 console_cursor_wrap_offset(cl->line, columns, &offl, &offc, cl->line + cl->cursor);
144 pen[0] = cwidth * offc;
145 pen[1] = -tvc->lheight * offl;
146
147 console_cursor_wrap_offset(cl->line + cl->cursor, columns, &offl, &offc, nullptr);
148 pen[1] += tvc->lheight * offl;
149
150 pen[0] += tvc->draw_rect.xmin;
151 pen[1] += tvc->draw_rect.ymin;
152 }
153
154 /* cursor */
156 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
159
160 immRectf(pos, pen[0] - U.pixelsize, pen[1], pen[0] + U.pixelsize, pen[1] + tvc->lheight);
161
163}
164
165static void console_textview_const_colors(TextViewContext * /*tvc*/, uchar bg_sel[4])
166{
168}
169
170static void console_textview_draw_rect_calc(const ARegion *region,
171 rcti *r_draw_rect,
172 rcti *r_draw_rect_outer)
173{
174 const int margin = 4 * UI_SCALE_FAC;
175 r_draw_rect->xmin = margin;
176 r_draw_rect->xmax = region->winx - V2D_SCROLL_WIDTH;
177 r_draw_rect->ymin = margin;
178 /* No margin at the top (allow text to scroll off the window). */
179 r_draw_rect->ymax = region->winy;
180
181 r_draw_rect_outer->xmin = 0;
182 r_draw_rect_outer->xmax = region->winx;
183 r_draw_rect_outer->ymin = 0;
184 r_draw_rect_outer->ymax = region->winy;
185}
186
188 const ARegion *region,
189 const bool do_draw,
190 const int mval[2],
191 void **r_mval_pick_item,
192 int *r_mval_pick_offset)
193{
194 ConsoleLine cl_dummy = {nullptr};
195 int ret = 0;
196
197 const View2D *v2d = &region->v2d;
198
199 TextViewContext tvc = {0};
200
203
209
210 tvc.arg1 = sc;
211 tvc.arg2 = nullptr;
212
213 /* view */
214 tvc.sel_start = sc->sel_start;
215 tvc.sel_end = sc->sel_end;
216 tvc.lheight = sc->lheight * UI_SCALE_FAC;
217 tvc.scroll_ymin = v2d->cur.ymin;
218 tvc.scroll_ymax = v2d->cur.ymax;
219
221
222 /* Nudge right by half a column to break selection mid-character. */
223 int m_pos[2] = {mval[0], mval[1]};
224 /* Mouse position is initialized with max int. */
225 if (m_pos[0] != INT_MAX) {
226 m_pos[0] += tvc.lheight / 4;
227 }
228
229 console_scrollback_prompt_begin(sc, &cl_dummy);
230 ret = textview_draw(&tvc, do_draw, m_pos, r_mval_pick_item, r_mval_pick_offset);
231 console_scrollback_prompt_end(sc, &cl_dummy);
232
233 return ret;
234}
235
237{
238 const int mval[2] = {INT_MAX, INT_MAX};
239 console_textview_main__internal(sc, region, true, mval, nullptr, nullptr);
240}
241
243{
244 const int mval[2] = {INT_MAX, INT_MAX};
245 return console_textview_main__internal(sc, region, false, mval, nullptr, nullptr);
246}
247
248int console_char_pick(SpaceConsole *sc, const ARegion *region, const int mval[2])
249{
250 int mval_pick_offset = 0;
251 void *mval_pick_item = nullptr;
252
253 console_textview_main__internal(sc, region, false, mval, &mval_pick_item, &mval_pick_offset);
254 return mval_pick_offset;
255}
#define BLI_assert(a)
Definition BLI_assert.h:46
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
int BLI_str_utf8_char_width_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_str_utf8_size_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
unsigned char uchar
unsigned int uint
#define UNLIKELY(x)
@ CONSOLE_LINE_INFO
@ CONSOLE_LINE_ERROR
@ CONSOLE_LINE_INPUT
@ CONSOLE_LINE_OUTPUT
#define UI_SCALE_FAC
void immUnbindProgram()
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
void immUniformThemeColor(int color_id)
GPUVertFormat * immVertexFormat()
void immRectf(uint pos, float x1, float y1, float x2, float y2)
@ GPU_SHADER_3D_UNIFORM_COLOR
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
Read Guarded memory(de)allocation.
@ TH_CONSOLE_SELECT
@ TH_CONSOLE_ERROR
@ TH_CONSOLE_CURSOR
@ TH_CONSOLE_INFO
@ TH_CONSOLE_OUTPUT
@ TH_CONSOLE_INPUT
@ TH_TEXT
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
#define V2D_SCROLL_WIDTH
Definition UI_view2d.hh:54
#define U
void console_textview_main(SpaceConsole *sc, const ARegion *region)
void console_scrollback_prompt_end(SpaceConsole *sc, ConsoleLine *cl_dummy)
static enum eTextViewContext_LineFlag console_line_data(TextViewContext *tvc, uchar fg[4], uchar[4], int *, uchar[4], uchar[4])
int console_textview_height(SpaceConsole *sc, const ARegion *region)
void console_scrollback_prompt_begin(SpaceConsole *sc, ConsoleLine *cl_dummy)
static int console_textview_step(TextViewContext *tvc)
static void console_textview_const_colors(TextViewContext *, uchar bg_sel[4])
static int console_textview_begin(TextViewContext *tvc)
static void console_textview_line_get(TextViewContext *tvc, const char **r_line, int *r_len)
static void console_textview_draw_rect_calc(const ARegion *region, rcti *r_draw_rect, rcti *r_draw_rect_outer)
static void console_textview_end(TextViewContext *tvc)
int console_char_pick(SpaceConsole *sc, const ARegion *region, const int mval[2])
static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int columns)
static int console_textview_main__internal(SpaceConsole *sc, const ARegion *region, const bool do_draw, const int mval[2], void **r_mval_pick_item, int *r_mval_pick_offset)
static void console_cursor_wrap_offset(const char *str, int width, int *row, int *column, const char *end)
#define str(s)
uint pos
uint col
format
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
return ret
void * last
ListBase scrollback
enum eTextViewContext_LineFlag(* line_data)(TextViewContext *tvc, uchar fg[4], uchar bg[4], int *r_icon, uchar r_icon_fg[4], uchar r_icon_bg[4])
Definition textview.hh:51
const void * arg2
Definition textview.hh:46
const void * arg1
Definition textview.hh:45
const void * iter
Definition textview.hh:60
void(* end)(TextViewContext *tvc)
Definition textview.hh:44
void(* const_colors)(TextViewContext *tvc, unsigned char bg_sel[4])
Definition textview.hh:59
int(* begin)(TextViewContext *tvc)
Definition textview.hh:43
void(* line_get)(TextViewContext *tvc, const char **r_line, int *r_len)
Definition textview.hh:50
int(* step)(TextViewContext *tvc)
Definition textview.hh:49
rcti draw_rect_outer
Definition textview.hh:37
void(* draw_cursor)(TextViewContext *tvc, int cwidth, int columns)
Definition textview.hh:57
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
int textview_draw(TextViewContext *tvc, const bool do_draw, const int mval_init[2], void **r_mval_pick_item, int *r_mval_pick_offset)
Definition textview.cc:303
eTextViewContext_LineFlag
Definition textview.hh:17
@ TVC_LINE_FG
Definition textview.hh:18