Blender  V3.3
space_console.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <stdio.h>
8 #include <string.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_blenlib.h"
13 #include "BLI_utildefines.h"
14 
15 #include "BKE_context.h"
16 #include "BKE_global.h"
17 #include "BKE_screen.h"
18 
19 #include "ED_screen.h"
20 #include "ED_space_api.h"
21 
22 #include "RNA_access.h"
23 #include "RNA_path.h"
24 
25 #include "WM_api.h"
26 #include "WM_types.h"
27 
28 #include "UI_resources.h"
29 #include "UI_view2d.h"
30 
31 #include "console_intern.h" /* own include */
32 
33 /* ******************** default callbacks for console space ***************** */
34 
36 {
37  ARegion *region;
38  SpaceConsole *sconsole;
39 
40  sconsole = MEM_callocN(sizeof(SpaceConsole), "initconsole");
41  sconsole->spacetype = SPACE_CONSOLE;
42 
43  sconsole->lheight = 14;
44 
45  /* header */
46  region = MEM_callocN(sizeof(ARegion), "header for console");
47 
48  BLI_addtail(&sconsole->regionbase, region);
49  region->regiontype = RGN_TYPE_HEADER;
51 
52  /* main region */
53  region = MEM_callocN(sizeof(ARegion), "main region for text");
54 
55  BLI_addtail(&sconsole->regionbase, region);
56  region->regiontype = RGN_TYPE_WINDOW;
57 
58  /* keep in sync with info */
59  region->v2d.scroll |= V2D_SCROLL_RIGHT;
60  region->v2d.align |= V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y; /* align bottom left */
61  region->v2d.keepofs |= V2D_LOCKOFS_X;
63  region->v2d.keeptot = V2D_KEEPTOT_BOUNDS;
64  region->v2d.minzoom = region->v2d.maxzoom = 1.0f;
65 
66  /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
67  // region->v2d.keepzoom = (V2D_KEEPASPECT|V2D_LIMITZOOM);
68 
69  return (SpaceLink *)sconsole;
70 }
71 
72 /* not spacelink itself */
73 static void console_free(SpaceLink *sl)
74 {
75  SpaceConsole *sc = (SpaceConsole *)sl;
76 
77  while (sc->scrollback.first) {
79  }
80 
81  while (sc->history.first) {
83  }
84 }
85 
86 /* spacetype; init callback */
88 {
89 }
90 
92 {
93  SpaceConsole *sconsolen = MEM_dupallocN(sl);
94 
95  /* clear or remove stuff from old */
96 
97  /* TODO: duplicate?, then we also need to duplicate the py namespace. */
98  BLI_listbase_clear(&sconsolen->scrollback);
99  BLI_listbase_clear(&sconsolen->history);
100 
101  return (SpaceLink *)sconsolen;
102 }
103 
104 /* add handlers, stuff you only do once or on area/region changes */
106 {
107  wmKeyMap *keymap;
108  ListBase *lb;
109 
110  const float prev_y_min = region->v2d.cur.ymin; /* so re-sizing keeps the cursor visible */
111 
112  /* force it on init, for old files, until it becomes config */
113  region->v2d.scroll = (V2D_SCROLL_RIGHT);
114 
115  UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_CUSTOM, region->winx, region->winy);
116 
117  /* always keep the bottom part of the view aligned, less annoying */
118  if (prev_y_min != region->v2d.cur.ymin) {
119  const float cur_y_range = BLI_rctf_size_y(&region->v2d.cur);
120  region->v2d.cur.ymin = prev_y_min;
121  region->v2d.cur.ymax = prev_y_min + cur_y_range;
122  }
123 
124  /* own keymap */
125  keymap = WM_keymap_ensure(wm->defaultconf, "Console", SPACE_CONSOLE, 0);
127 
128  /* add drop boxes */
130 
132 }
133 
134 /* same as 'text_cursor' */
135 static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region)
136 {
137  int wmcursor = WM_CURSOR_TEXT_EDIT;
138  const wmEvent *event = win->eventstate;
139  if (UI_view2d_mouse_in_scrollers(region, &region->v2d, event->xy)) {
140  wmcursor = WM_CURSOR_DEFAULT;
141  }
142 
143  WM_cursor_set(win, wmcursor);
144 }
145 
146 /* ************* dropboxes ************* */
147 
148 static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
149 {
150  return WM_drag_get_local_ID(drag, 0) != NULL;
151 }
152 
153 static void id_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
154 {
155  ID *id = WM_drag_get_local_ID(drag, 0);
156 
157  /* copy drag path to properties */
158  char *text = RNA_path_full_ID_py(G_MAIN, id);
159  RNA_string_set(drop->ptr, "text", text);
160  MEM_freeN(text);
161 }
162 
163 static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
164 {
165  return (drag->type == WM_DRAG_PATH);
166 }
167 
168 static void path_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
169 {
170  char pathname[FILE_MAX + 2];
171  BLI_snprintf(pathname, sizeof(pathname), "\"%s\"", drag->path);
172  RNA_string_set(drop->ptr, "text", pathname);
173 }
174 
175 /* this region dropbox definition */
176 static void console_dropboxes(void)
177 {
179 
180  WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL, NULL);
181  WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL, NULL);
182 }
183 
184 /* ************* end drop *********** */
185 
186 static void console_main_region_draw(const bContext *C, ARegion *region)
187 {
188  /* draw entirely, view changes should be handled here */
190  View2D *v2d = &region->v2d;
191 
192  if (BLI_listbase_is_empty(&sc->scrollback)) {
193  WM_operator_name_call((bContext *)C, "CONSOLE_OT_banner", WM_OP_EXEC_DEFAULT, NULL, NULL);
194  }
195 
196  /* clear and setup matrix */
198 
199  /* Works best with no view2d matrix set. */
201 
202  /* data... */
203 
204  console_history_verify(C); /* make sure we have some command line */
205  console_textview_main(sc, region);
206 
207  /* reset view matrix */
209 
210  /* scrollers */
212 }
213 
214 static void console_operatortypes(void)
215 {
216  /* console_ops.c */
220 
224 
225  /* for use by python only */
228 
236 }
237 
238 static void console_keymap(struct wmKeyConfig *keyconf)
239 {
240  WM_keymap_ensure(keyconf, "Console", SPACE_CONSOLE, 0);
241 }
242 
243 /****************** header region ******************/
244 
245 /* add handlers, stuff you only do once or on area/region changes */
247 {
248  ED_region_header_init(region);
249 }
250 
251 static void console_header_region_draw(const bContext *C, ARegion *region)
252 {
253  ED_region_header(C, region);
254 }
255 
257 {
258  ScrArea *area = params->area;
259  ARegion *region = params->region;
260  wmNotifier *wmn = params->notifier;
261 
262  /* context changes */
263  switch (wmn->category) {
264  case NC_SPACE: {
265  if (wmn->data == ND_SPACE_CONSOLE) {
266  if (wmn->action == NA_EDITED) {
267  if ((wmn->reference && area) && (wmn->reference == area->spacedata.first)) {
268  /* we've modified the geometry (font size), re-calculate rect */
270  ED_region_tag_redraw(region);
271  }
272  }
273  else {
274  /* generic redraw request */
275  ED_region_tag_redraw(region);
276  }
277  }
278  break;
279  }
280  }
281 }
282 
284 {
285  SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype console");
286  ARegionType *art;
287 
288  st->spaceid = SPACE_CONSOLE;
289  strncpy(st->name, "Console", BKE_ST_MAXNAME);
290 
291  st->create = console_create;
292  st->free = console_free;
293  st->init = console_init;
294  st->duplicate = console_duplicate;
295  st->operatortypes = console_operatortypes;
296  st->keymap = console_keymap;
297  st->dropboxes = console_dropboxes;
298 
299  /* regions: main window */
300  art = MEM_callocN(sizeof(ARegionType), "spacetype console region");
301  art->regionid = RGN_TYPE_WINDOW;
303 
306  art->cursor = console_cursor;
307  art->event_cursor = true;
309 
310  BLI_addhead(&st->regiontypes, art);
311 
312  /* regions: header */
313  art = MEM_callocN(sizeof(ARegionType), "spacetype console region");
314  art->regionid = RGN_TYPE_HEADER;
315  art->prefsizey = HEADERY;
317 
320 
321  BLI_addhead(&st->regiontypes, art);
322 
324 }
struct SpaceConsole * CTX_wm_space_console(const bContext *C)
Definition: context.c:815
#define G_MAIN
Definition: BKE_global.h:267
#define BKE_ST_MAXNAME
Definition: BKE_screen.h:53
void BKE_spacetype_register(struct SpaceType *st)
Definition: screen.c:391
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
#define FILE_MAX
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED(x)
#define HEADERY
@ RGN_TYPE_WINDOW
@ RGN_TYPE_HEADER
@ RGN_ALIGN_BOTTOM
@ RGN_ALIGN_TOP
@ SPACE_CONSOLE
@ USER_HEADER_BOTTOM
@ V2D_KEEPTOT_BOUNDS
@ V2D_LOCKOFS_X
@ V2D_LIMITZOOM
@ V2D_LOCKZOOM_X
@ V2D_KEEPASPECT
@ V2D_LOCKZOOM_Y
@ V2D_SCROLL_RIGHT
@ V2D_ALIGN_NO_NEG_X
@ V2D_ALIGN_NO_NEG_Y
@ ED_KEYMAP_UI
Definition: ED_screen.h:691
@ ED_KEYMAP_HEADER
Definition: ED_screen.h:697
@ ED_KEYMAP_VIEW2D
Definition: ED_screen.h:694
void ED_region_header(const struct bContext *C, struct ARegion *region)
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
void ED_region_header_init(struct ARegion *region)
Definition: area.c:3417
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
@ TH_BACK
Definition: UI_resources.h:39
void UI_ThemeClearColor(int colorid)
Definition: resources.c:1448
void UI_view2d_region_reinit(struct View2D *v2d, short type, int winx, int winy)
Definition: view2d.cc:217
void UI_view2d_view_restore(const struct bContext *C)
char char UI_view2d_mouse_in_scrollers(const struct ARegion *region, const struct View2D *v2d, const int xy[2]) ATTR_NONNULL(1
void UI_view2d_view_ortho(const struct View2D *v2d)
void UI_view2d_scrollers_draw(struct View2D *v2d, const struct rcti *mask_custom)
@ V2D_COMMONVIEW_CUSTOM
Definition: UI_view2d.h:34
#define WM_DRAG_PATH
Definition: WM_types.h:1050
#define NA_EDITED
Definition: WM_types.h:523
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:208
#define ND_SPACE_CONSOLE
Definition: WM_types.h:462
#define NC_SPACE
Definition: WM_types.h:342
unsigned int U
Definition: btGjkEpa3.h:78
void console_textview_main(SpaceConsole *sc, const ARegion *region)
Definition: console_draw.c:225
void CONSOLE_OT_insert(struct wmOperatorType *ot)
Definition: console_ops.c:424
void CONSOLE_OT_unindent(struct wmOperatorType *ot)
Definition: console_ops.c:580
void CONSOLE_OT_copy(struct wmOperatorType *ot)
Definition: console_ops.c:1027
void console_textview_update_rect(SpaceConsole *sc, ARegion *region)
Definition: console_ops.c:45
void CONSOLE_OT_scrollback_append(struct wmOperatorType *ot)
Definition: console_ops.c:936
void CONSOLE_OT_paste(struct wmOperatorType *ot)
Definition: console_ops.c:1082
void CONSOLE_OT_select_word(struct wmOperatorType *ot)
Definition: console_ops.c:1260
void console_history_free(SpaceConsole *sc, ConsoleLine *cl)
Definition: console_ops.c:58
void console_scrollback_free(SpaceConsole *sc, ConsoleLine *cl)
Definition: console_ops.c:64
ConsoleLine * console_history_verify(const struct bContext *C)
void CONSOLE_OT_history_cycle(struct wmOperatorType *ot)
Definition: console_ops.c:829
void CONSOLE_OT_history_append(struct wmOperatorType *ot)
Definition: console_ops.c:885
void CONSOLE_OT_indent_or_autocomplete(struct wmOperatorType *ot)
Definition: console_ops.c:472
void CONSOLE_OT_move(struct wmOperatorType *ot)
Definition: console_ops.c:351
void CONSOLE_OT_delete(struct wmOperatorType *ot)
Definition: console_ops.c:675
void CONSOLE_OT_clear_line(struct wmOperatorType *ot)
Definition: console_ops.c:718
void CONSOLE_OT_indent(struct wmOperatorType *ot)
Definition: console_ops.c:526
void CONSOLE_OT_clear(struct wmOperatorType *ot)
Definition: console_ops.c:760
void CONSOLE_OT_select_set(struct wmOperatorType *ot)
Definition: console_ops.c:1210
Scene scene
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
static void area(int d1, int d2, int e1, int e2, float weights[2])
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
char * RNA_path_full_ID_py(Main *bmain, ID *id)
Definition: rna_path.cc:1182
static void console_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
static void console_operatortypes(void)
static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region)
static SpaceLink * console_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
Definition: space_console.c:35
void ED_spacetype_console(void)
static void console_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
Definition: space_console.c:87
static void console_free(SpaceLink *sl)
Definition: space_console.c:73
static void path_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
static void console_header_region_draw(const bContext *C, ARegion *region)
static SpaceLink * console_duplicate(SpaceLink *sl)
Definition: space_console.c:91
static void console_main_region_draw(const bContext *C, ARegion *region)
static void id_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
static void console_dropboxes(void)
static void console_main_region_listener(const wmRegionListenerParams *params)
static void console_keymap(struct wmKeyConfig *keyconf)
static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
static void console_main_region_init(wmWindowManager *wm, ARegion *region)
void(* draw)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:151
void(* cursor)(struct wmWindow *win, struct ScrArea *area, struct ARegion *region)
Definition: BKE_screen.h:179
void(* listener)(const wmRegionListenerParams *params)
Definition: BKE_screen.h:165
int keymapflag
Definition: BKE_screen.h:208
short event_cursor
Definition: BKE_screen.h:215
void(* init)(struct wmWindowManager *wm, struct ARegion *region)
Definition: BKE_screen.h:147
ListBase handlers
short alignment
short regiontype
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
ListBase regionbase
ListBase scrollback
float minzoom
short align
short keeptot
short keepzoom
short keepofs
short scroll
float maxzoom
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
char path[1024]
Definition: WM_types.h:1150
int type
Definition: WM_types.h:1148
struct PointerRNA * ptr
Definition: WM_types.h:1237
unsigned int data
Definition: WM_types.h:308
unsigned int action
Definition: WM_types.h:308
unsigned int category
Definition: WM_types.h:308
void * reference
Definition: WM_types.h:310
struct wmKeyConfig * defaultconf
struct wmEvent * eventstate
void WM_cursor_set(wmWindow *win, int curs)
Definition: wm_cursors.c:126
@ WM_CURSOR_DEFAULT
Definition: wm_cursors.h:18
@ WM_CURSOR_TEXT_EDIT
Definition: wm_cursors.h:19
ID * WM_drag_get_local_ID(const wmDrag *drag, short idcode)
Definition: wm_dragdrop.cc:531
ListBase * WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
Definition: wm_dragdrop.cc:76
wmDropBox * WM_dropbox_add(ListBase *lb, const char *idname, bool(*poll)(bContext *, wmDrag *, const wmEvent *), void(*copy)(bContext *, wmDrag *, wmDropBox *), void(*cancel)(Main *, wmDrag *, wmDropBox *), WMDropboxTooltipFunc tooltip)
Definition: wm_dragdrop.cc:95
wmEventHandler_Dropbox * WM_event_add_dropbox_handler(ListBase *handlers, ListBase *dropboxes)
wmEventHandler_Keymap * WM_event_add_keymap_handler_v2d_mask(ListBase *handlers, wmKeyMap *keymap)
int WM_operator_name_call(bContext *C, const char *opstring, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:852
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))